2016-06-09 40 views
0

jQuery - replaceWith更新HTML不會使圖像或鏈接

我正在寫一個JavaScript代碼(使用jQuery和Knockout)和HTML,接受用戶輸入(GitHub用戶名)的小代碼,檢查輸入是否有效對GitHub api,並顯示用戶的GitHub頭像和用戶名(鏈接到GitHub上的匹配配置文件)。顯示屏會替換用戶輸入用戶名的表單。

用戶輸入之前的原始HTML是:

<div id="inputSection"> 
    <form> 
     <p> 
      GitHub Username: 
       <input type="text" name="username" value="" placeholder="username" id="un"/> 
       <button type="button" id="submitButton">Login</button> 
     </p> 
    </form> 
</div> 

和代碼來代替它的是:

$("#submitButton").click(function() { 
    var username = document.getElementById('un').value; 
    var inputForm = $(document.getElementById('inputSection')); 

    $.ajax({ 
     ... 
     success: function() { 
      alert("Welcome, " + username); 
      var userURL = 'https://github.com/' + username; 
      var inputContent = $('<a data-bind="attr: {href: userURL}"><img data-bind="attr: {src: avatar_url}" height=\"30\" width=\"30\"/>' + username + '</a>'); 
      $(inputForm.replaceWith(inputContent)); 
      } 
    }); 
}); 

這似乎大部分工作。警報在通過用戶名歡迎用戶後,表單從網頁中消失。它被用戶名所替代,該用戶名被格式化爲鏈接。但是,它不起作用。點擊它不會做任何事情。此外,用戶的頭像,儘管在網頁上顯示一組大小的設置,卻沒有出現。

該解決方案可能非常簡單明顯,但由於本週我纔開始學習這些語言和庫,我不確定發生了什麼問題。敲除應該運行在調用JavaScript頁面的HTML頁面上,並且ajax正在處理其他函數,所以我認爲沒關係。值「avatar_url」是使用ajax在https://api.github.com/users請求的api的一部分。

我已經嘗試了各種不同的東西,沒有效果。如果您需要更多信息或有更好的建議,請發表評論。我是編程和堆棧溢出的新手,但我想盡可能使我的程序和我的問題都儘可能好。感謝您的時間。

編輯:1.我最初未能設置圖像的大小,導致一個0x0圖像。儘管圖像本身仍然不顯示,但這已得到糾正。 2.當我第一次加入我的代碼時,我試圖通過排除其中一些變量已被重命名爲其他不相關部分並僅使兩個相關片段之間的所有名稱匹配來更容易閱讀。我沒有抓住他們。他們應該現在都匹配。

回答

2

簡短的回答:

你將與數據結合的HTML元素沒有明確初始化其綁定。在DOM的新注入部分使用ko.applyBindings(vm, node)

龍答:

如果你是新來編碼和雙方jQuery和淘汰賽,我建議在一次不使用這兩個庫。這裏的原因:

如果你想使用淘汰賽,你必須堅持某一種軟件架構:

簡化動態JavaScript的用戶界面與模型 - 視圖 - 視圖模型(MVVM)( http://knockoutjs.com/

另一方面,jQuery更像是一個工具箱。它並不決定一個架構模式。

它使諸如HTML文檔遍歷和操縱,事件處理,動畫和Ajax之類的東西簡單得多,而且易於使用,可用於多種瀏覽器。 (https://jquery.com/

這聽起來有點跛,是不是一個真正的答案,但我會告訴你解決你的問題「淘汰賽的方式」之間的差異,「jQuery的方式」。我會與後者開始,因爲它是最接近你目前的做法:

jQuery的方法(請注意,我跳過阿賈克斯部分)

找到你需要讓你的UI交互元素。將事件監聽器附加到按鈕上,當新數據可用時修改DOM。

$(document).ready(function() { 
 
    // Notice that you don't need document.getElementById 
 
    var submitButton = $("#loginButton"); 
 
    var userNameInput = $("#un"); 
 
    var inputSection = $("#inputSection"); 
 

 
    var getContentString = function(userName) { 
 
    var userUrl = "https://github.com/" + userName; 
 
    var avatarUrl = "..."; 
 

 
    // Inject the user specific attributes 
 
    return "<a href=`" + userUrl + "`><img src=`" + avatarUrl + "` height='30' width='30'/>" + userName + "</a>"; 
 
    }; 
 

 

 
    var onSubmitClick = function(event) { 
 
    var userName = userNameInput.val(); 
 
    var onSuccess = function() { 
 
     // Create new <a> element and replace the form with the new HTML 
 
     var inputContent = $(getContentString(userName)); 
 
     inputSection.replaceWith(inputContent); 
 
    }; 
 

 
    /* 
 
    $.ajax({ 
 
     
 
     success: onSuccess 
 
    }); 
 
    */ 
 

 
    //Just call onSuccess to circumvent unimplemented ajax: 
 
    onSuccess(); 
 
    }; 
 

 
    submitButton.click(onSubmitClick); 
 

 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<form id="inputSection"> 
 
    <p> 
 
    GitHub Username: 
 
    <input type="text" name="username" value="" placeholder="username" id="un" /> 
 
    <button type="button" id="loginButton">Login</button> 
 
    </p> 
 
</form>

敲除的方法

爲您的用戶視圖模型。綁定輸入並自動計算其他屬性。通過數據綁定附加事件監聽器。使用if,visibletemplate綁定來交換部分UI。

var UserViewModel = function() { 
 

 
    this.userName = ko.observable(""); 
 
    this.confirmed = ko.observable(false); 
 

 
    this.userUrl = ko.computed(function() { 
 
    return "https://github.com/" + this.userName(); 
 
    }, this); 
 

 
    this.avatarUrl = ko.computed(function() { 
 
    return "???" + this.userName(); 
 
    }, this); 
 
}; 
 

 
UserViewModel.prototype.confirm = function() { 
 
    /* ajax (disabled for example) 
 
    $.ajax({ 
 
    success: this.confirmed.bind(null, true) 
 
    }); 
 
    */ 
 

 
    this.confirmed(true); 
 
}; 
 

 
var viewModel = { 
 
    user: new UserViewModel() 
 
}; 
 

 
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<div data-bind="with: user"> 
 
    <!-- ko ifnot: confirmed --> 
 
    <form> 
 
    <p> 
 
     GitHub Username: 
 
     <input data-bind="value: userName" type="text" placeholder="username" /> 
 
     <button data-bind="click: confirm">Login</button> 
 
    </p> 
 
    </form> 
 
    <!-- /ko --> 
 

 
    <!-- ko if: confirmed --> 
 
    <a data-bind="attr: { href: userUrl }"> 
 
    <img data-bind="attr: {src: avatarUrl }" /> 
 
    <span data-bind="text: userName"></span> 
 

 
    </a> 
 
    <!-- /ko --> 
 

 
</div>

+0

長答案jQuery方法中的getContentString中的反引號似乎是不必要的,並導致問題。嘗試它們時我可能做錯了。你能解釋一下他們的功能嗎? – deadandhallowed

+1

後面的蜱是爲了單引號(爲了避開它們)。對於那個很抱歉... – user3297291

0

與user3297291的jQuery的幫助下回答上面,我終於來到了這一點。對於這種進展,答案是好的和必要的。有些部分在這種情況下無法正常工作(大部分簡單的兼容性問題與本示例中未包含的其他代碼有關)。雖然這是一個非常具體的問題,但我認爲應該包括解決方案。請注意,我決定暫時遠離Knockout。

將id附加到表單而不是div的HTML建議是一個很好的舉措。

$("#submitButton").click(function inputForm() { 
    var username = $("#un").val(); 

    function makeUserContent(user, profile, avatar) { //arguments are data from ajax 
     //writes a string without the messy quotes within quotes within quotes problem 
     //much clearer than trying to handle the jQuery and string all at once 
     return "<a href=" + profile + "><img src=" + avatar + " height='30' width='30' />" + user + "</a>"; 
    } 

    function submitUsername() { 
     $.ajax({ 
      ... 
      success: function correntInformation(data) { 
       //data is what the ajax gets, which is passed for use 
       alert("Welcome, " + username + "."); 
       //calls to make the string with the data gotten by ajax 
       var inputContent = $(makeUserContent(data.login, data.html_url, data.avatar_url)); 
       $("#inputSection").replaceWith(inputContent); 
      } 
     }) 
    } 
    submitUsername(); 
}) 

我從這個問題拿走了最重要的事情是這樣的:簡化字符串,並保持在同一時間(與之前都經歷)使用的數據,一個圖書館工作。