2013-10-17 51 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