2013-10-17 21 views
0

我有一个页面,我想要更改使用哪个模板来显示项目列表(例如简单vs高级视图)。示例代码:模板绑定更改时不会更改模板

<script type="text/html" id="template1"> 
    Template 1 
</script> 

<script type="text/html" id="template2"> 
    Template 2 
</script> 

<input type="checkbox" data-bind="checked: viewSelect"/> 
<button data-bind="click: newArray">Refresh Array</button> 
<ul data-bind="template:{name: templateBinding, foreach: items}"> 
</ul> 

JS:

var ViewModel = function(){ 
    var self = this; 

    this.viewSelect = ko.observable(); 

    this.newArray = function(){ 
     console.log("newArray"); 
     self.items([{text:"Item1"},{text:"Item2"},{text:"Item3"}]); 
    }; 

    this.templateBinding = ko.computed(function(){ 
     console.log("templateBinding"); 
     if(self.viewSelect()){ 
      return "template1"; 
     } else{ 
      return "template2"; 
     } 
    }); 

    this.items = ko.observableArray([{text:"Item1"},{text:"Item2"},{text:"Item3"}]); 
}; 

ko.applyBindings(new ViewModel()); 

我创建a fiddle与此代码。

发生了什么:我期望Knockout在模板更改时重新创建显示的列表。挂钩到templateBindingcomputed被调用(这可以从控制台确认),但模板不会更改,切换复选框不会更改显示。但是,对数组内容的更改不会使用新模板刷新列表。

有没有这样做的优雅方式,或者我做错了什么?

回答

2

当在foreach中为项目使用动态模板名称时,您需要指定一个要执行的函数。这将被称为每个项目(并将通过该项目作为第一个参数)。

所以,你可以在你当前的代码更改为:

this.getTemplate = function(){ 
    if(self.viewSelect()){ 
     return "template1"; 
    } else{ 
     return "template2"; 
    } 
}; 

和绑定,如:

<ul data-bind="template:{name: getTemplate, foreach: items}"> 

这里是一个更新的小提琴:http://jsfiddle.net/rniemeyer/qAEXh/

+0

作品一种享受。虽然我想知道为什么这会起作用,但是绑定到可观察对象却没有。 –

+0

就是模板绑定当前与'foreach'一起使用的方式。当调用每个函数时,它确保每个函数都有自己的依赖关系。 –

+0

使用与KO其余部分相同的可观察模式会不会更好? :D – Anders