2011-09-13 28 views
1

所以,我有可观察的数组与网站,这是通过模板显示。如果我将网站添加到此数组,模板不会更新,但如果我将数组从网站中移除 - 瞧!模板已更新,并且所有之前添加的网站也显示出来了。KnockoutJS:模板没有更新可观察的数组更改(仅在添加时,在删除时起作用)

如果我将使用漂亮的黑客(在代码中注释)与整个数组替换为新的,那么一切正常。

顺便说一句,我通过AJAX加载模板,并在之后使用“ko.applyBindings(viewModel)”。我认为工作正常,因为初始网站显示正确。

$(function(){ 

//site entry in user's sites list 
var siteObject = function(url, lastChecked, status){ 
    this.url = url; 
    this.lastChecked = (lastChecked == 'undefined') ? '' : lastChecked; 
    this.status = (status == 'undefined') ? 'not_checked_yet' : status; 
    this.toDelete = false; 
    this.remove = function() {viewModel.sites.remove(this)}; 
}; 

viewModel = { 
    //=========== sites list managment ========================== 
    sites: ko.observableArray(), 
    //on "add" click in "add site" form 
    addSite: function(){ 
     var $form = $('#add_site_form'); 
     var siteUrl = $form.find('input[name="site"]').val(); 

     /*nifty hack <---- 
     var sites = this.sites(); 
     sites.push(new siteObject(siteUrl)); 
     this.sites(sites);*/ 

     this.sites.push(new siteObject(siteUrl)); 
    }, 
    //on "remove sites" button click 
    removeSites: function() { 
     var sitesToRemove = []; 
     $.each(this.sites(), function(){ 
      if (this.toDelete) sitesToRemove.push(this); 
     }); 
     if (sitesToRemove.length == 0) 
      alert("Ни одного сайта не было выбрано для удаления."); 
     else { 
      var message = "Вы точно хотите перестать отслеживать"; 
      for (var i in sitesToRemove) { 
       message += "\n\"" + sitesToRemove[i].url + "\""; 
      } 
      message += "?"; 
      if (confirm(message)) { 
       $.each(sitesToRemove, function(){this.remove()}); 
       //save new sites list to db 
       this.saveSitesListToDb(); 
      } 
     } 
     //hide form 
     $('#remove_sites_form').slideToggle(); 
     //toggle checkboxes 
     $('#content_sites_list .site_info input[type="checkbox"]').slideToggle(); 
    }; 

而且模板:

<!-- end of menu --> 
<div id="content_sites_list" 
    class="grid_12" 
    data-bind="template: {name: 'sites_list_template', foreach: sites}"></div> 

    <!-- Templates --> 

    <script id="sites_list_template" type="text/x-jquery-tmpl"> 
    <div class="site"> 
     <div class="site_panel grid_12"> 
      <div class="site_info"> 
       &ndash; 
       <input type="checkbox" value="${url}" 
         class="delete_checkbox" data-bind="checked: toDelete" /> 
       <a href="${url}" class="show_site_stat">${url.substr(7)}</a> 
       {{if status == "200"}} 
        <img src="img/green_light.png" alt="ok"/> 
       {{/if}}    
      </div> 
      <div class="site_stat"> 
       <div class="site_last_check">Последняя проверка: ${dateTimestamp}</div> 
      </div> 
     </div> 
    </div> 
    </script> 

我在knockoutjs和稳定的一个尝试这种在最新的测试版。

+0

如果你改变'this.sites.push(新siteObject(SITEURL));''来sites.push(新siteObject(SITEURL ));'它有什么区别? – ipr101

+0

是的,它不会工作)this.sites() - 是淘汰赛的可观察数组。网站 - 是由可观察数组+新对象创建的本地数组。 – Dimitry

+1

您的示例适用于我的小编辑,包括正确关闭$(function(){})中的花括号和圆括号。 顺便说一下,我认为最好让siteUrl成为视图模型的成员,然后将其绑定到某个复选框,而不是使用jQuery选择器搜索它。 – STO

回答

1

我做了一个jsFiddle它工作正常。

JSLint曾在viewModel的removeSites函数中抱怨过一些问题。我修复了这些问题,并添加了一个按钮和输入框,以便能够输入一些内容,并且一切顺利。

所以,你可以尝试更新removeSites功能,看看它是否可以帮助你,

+0

哇,thx!似乎问题出在AJAX模板中,因为你的代码与我的代码很相似。我会尝试将其包含在索引页中。另外我会尝试在1.3.0中使用淘汰赛的新模板引擎 – Dimitry

相关问题