2012-01-09 138 views
2

有誰知道我會如何用knockoutJS完成以下模式? 我一直在apache flex中使用這個模式,並想看看我是否可以模仿它。 我不確定如何用另一個替換observable。任何幫助/想法非常讚賞。選擇對象模式與淘汰賽

//模型

myViewModel = { 
items : ko.observableArray(), 
selected_item : ko.observable() 
} 

//視圖

<h3 data-bind="text : myViewModel.selected_item.name"> </h3> 
<ul> 
<!-- ko foreach: myViewModel.items --> 
<li data-bind="text : name"/> 
<!-- /ko --> 
</ul> 

//邏輯

$('li').click(function(e){ 
    //check ko.dataFor(this) has different id from that of myViewModel.selected_item 
    //if id different 
    //set myViewModel.selected_item to ko.dataFor(this) 
    //rejoice as h3 text changes 
}) 

回答

9

你是在正確的軌道上。有幾種模式可用於選擇所選項目。如果你想不加區分地附加一個點擊處理程序,就像你上面那樣,那麼你最好的辦法就是使用一個委託處理程序,這樣你就可以設置處理對你的observableArray的更改。委託處理程序將能夠處理添加的新元素。

所以,你可以這樣做:

$("#content").on("click", "li", function(e) { 
    var item = ko.dataFor(this), 
     current = myViewModel.selected_item; 

    if (!current() || item.id !== current().id) { 
     current(item); 
    } 
}); 

這裏有一個例子:http://jsfiddle.net/rniemeyer/hBUBN/

當您綁定到h3,因爲selected_item可以爲空,你將需要通過包裝來保護自己在一個with塊(在這個例子中),調用一個處理null的函數,或者在像(data-bind="text: myViewModel.selected_item() ? myViewModel.selected_item().id : 'unknown'")這樣的綁定中進行。爲了保持它的乾淨,這個邏輯可以放在一個函數中,你可以從你的數據綁定中調用函數,或者使用with來防止這個問題(儘管當它爲空時它什麼也不渲染)。

否則,你甚至可以只是這樣做:

<!-- ko foreach: myViewModel.items --> 
    <li data-bind="text : name, click: $parent.selected_item"></li> 
<!-- /ko --> 

click(和event)在KO 2.0結合傳遞當前數據作爲第一個參數。您可以使用$parent變量訪問一個範圍級別(或$root以達到基本級別)。可觀察對象是函數,您可以通過將新值作爲第一個參數來設置它們的值。因此,在這裏做$parent.selected_item將調用傳遞數據的observable函數作爲第一個參數。因此,它會將您選擇的值設置爲適當的項目。

樣品:http://jsfiddle.net/rniemeyer/gemug/

+1

+1通常我喜歡把邏輯在其自己的方法,但對於簡單,簡短而親切的@RPNiemeyer的第二個例子東西,我只是與在線解決方案去。像魅力一樣工作 – 2012-01-09 17:28:52

+0

我通常也使用另一種方法,部分是爲了運行其他邏輯,主要是因爲當方法是一個名詞('click:$ parent.selected_item')而不是動詞('click:$ parent .selectItem') – 2012-01-09 17:35:05

+0

完美 - 謝謝,這對我有很大的幫助。我最終在標記中使用了指令(小提琴#2)。而不是使用div來包裝綁定,但是我使用了ko指令。 <! - ko with:selected_item - >此處綁定 Chin 2012-01-10 04:34:52