2012-08-16 72 views
2

給定一個映射到knockout.js和使用custom templates的數組,如何讓數組中的每個項目使用不同的模板呈現?Knockoutjs爲每個項目選擇一個自定義模板

這裏是一個鏈接到an example on jsFiddle所需的功能 - 有些人會希望它會。

簡單來說,給出一個數組是這樣的:

people: ko.observableArray([ 
    { name: 'Rod', age: 123, template: 'personItem' }, 
    { name: 'IBM', incorporated: 1911, template: 'corporateItem' }, 
]) 

怎麼能建立一個foreach:結合使用的一些項目,以及爲他人不同的模板一個模板。

(注:我知道的是,使用下劃線模板有點合併了有關的問題,任何不必要的混亂表示歉意)

我曾經想過用一個模板,一組if綁定 - 一個每個模板類型,像這樣:

<div data-bind='foreach: people'> 
    <div data-bind='if: people.template() == "personItem"'> 
    </div> 
    <div data-bind='if: people.template() == "corporateItem"'> 
    </div> 
</div> 

這似乎相當不雅,我懷疑(希望)有一個更優雅的和非常簡單的選擇。

任何想法將不勝感激&感謝您的閱讀。

回答

15

而不是將字符串傳遞給template綁定的參數name,您可以實際傳遞一個函數來確定模板。您必須將此與您的案例中的foreach選項結合使用,而不是通過您的項目執行「每個」。

所以,你的視圖模型會是什麼樣子:

var viewModel = { 
    people: ko.observableArray([ 
     { name: 'Rod', age: 123, template: 'personItem' }, 
     { name: 'IBM', incorporated: 1911, template: 'corporateItem' }, 
    ]), 
    getTemplate: function(item) { 
     return item.template; 
    } 
}; 

和你的標記會是這樣:

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

<script type="text/html" id="personItem"> 
     <li> 
      <b data-bind="text: name"></b> is <%= age %> years old 
     </li> 
</script> 

<script type="text/html" id="corporateItem"> 
     <li> 
      <b data-bind="text: name"></b> is <%= incorporated %> years old 
     </li> 
</script> 

下面是一個例子:http://jsfiddle.net/rniemeyer/xF2xe/

下面是一些額外的參考材料:

+0

太謝謝你了。這是一個很好的答案,也是一個很好的例子。 – 2012-08-16 03:25:36

+0

這個問題的補充,我注意到,不能動態改變模板類型,就像在[this jsFiddle]中所期望的那樣(http://jsfiddle.net/bmh_ca/xF2xe/1/ - 我想知道這是否可能,或者是否必須移除並替換數組中的某個元素才能更改模板類型 – 2012-08-16 15:24:50

+0

它實際上是在嘗試更改模板,但是在運行模板時遇到「合併」問題時會遇到問題。一個例子,我用模板中的'$ data.incorporated'替換它,因爲它將返回null而不是錯誤。http://jsfiddle.net/rniemeyer/xF2xe/2/ – 2012-08-16 17:18:04