2012-06-13 102 views
0

第一:我是新的敲除js,並試圖圍繞淘汰賽/ mvvm的思維方式來包裹我的頭,所以請原諒我,如果我的問題變得微不足道。Knockout.js和twoway綁定的複選框

我所得到的是以下情況:我有一個包含選定票證對象的observableArray的敲出視圖模型。此數組表示用戶定義的選擇/更大的一組票的子集。整組票據列在一個jqgrid表中,並且每行都有一個複選框,這個複選框應該是告訴每張票是否被選中。這意味着只要「selectedTickets」數組發生更改,複選框的值就需要更新。除此之外,我還希望用戶能夠單擊每個複選框,以便從選擇中添加/刪除票證。似乎是一個相當可以接受的功能塊,對吧?

但是,我確實無法看到如何使用敲擊「檢查」綁定,以實現此目的。我的第一個想法是在視圖模型對象上使用名爲「isSelected」的計算/依賴觀察值,它將反映selectedTickets數組中的更改,並基於票是否位於selectedTickets數組中而返回true或false。這裏的第一個問題是,我需要傳遞一個參數給計算的observable,說明它應該查找哪個票證ID,以及從我所看到的只能用於可寫計算的observable。然而,獲取複選框的狀態並不像寫操作,因此已經開始聞起來有些東西了。下一個問題是綁定需要雙向,因爲我希望用戶能夠更改每個複選框的狀態,並相應地更新selectedTickets數組。這是一個不同的操作,因爲它實際上將刪除/添加票到selectedTickets數組。這將再次觸發試圖設置複選框狀態的計算觀察值。看起來像這兩個用例可能最終會像一個無限循環,如果我試圖這樣做。我還沒有找到一種將這兩個用例組合在一起的好方法,只需使用勾選的複選框。

我當然可以在複選框上手動執行事件處理,將偵聽器連接到複選框上的已更改事件並將其添加到淘汰視圖模型中的selectedTickets數組中,但我希望可以使用淘汰賽更自動化綁定。

希望有一些淘汰賽的大師可以引導我走上一條很好的道路,因爲我覺得我已經駕駛這輛賽車脫離了賽道。

+6

人們不喜歡文本牆,也許你可以更明確地描述你的問題? – Christoph

+2

我認爲你的意思是簡潔。他已經非常明確了! :) –

回答

6

當使用knockout.js時,你需要停止做一半事情 - 如果你有一個項目列表,數據屬於視圖模型(不僅僅是選擇項目),並且只有外觀由視圖定義。

因此,我建議Item類型的可觀察到的陣列items,其中有一個屬性isSelected - 所選的項目然後可以通過一個可觀察到的計算由訪問:

var Item = function(name) { 
    this.name = ko.observable(name); 
    this.isSelected = ko.observable(false); 
}; 

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

    self.items = ko.observableArray([ 
     new Item('Foo'), new Item('Bar'), new Item('Foo Bar') 
    ]); 

    self.selectedItems = ko.computed(function() { 
     return ko.utils.arrayFilter(self.items(), function(item) { 
      return item.isSelected(); 
     }); 
    }); 
}; 

http://jsfiddle.net/htZfX/

+0

我認爲你的承諾是正確的。我有一種感覺,我建立視角模型的方式存在一個主要缺陷,我認爲您已經接受了!我之所以最終只在viewmodel中擁有選定的票據是因爲我沒有從這個應用程序的開始使用knockout。我一直在想我想測試淘汰賽js,然後憑藉這種新的「選票」功能(多個來源修改選擇列表,++),我認爲這是一個完美的用例。我想通過不重做整個應用程序來降低風險。也許這是一個不好的選擇? –

+0

後續問題:我看到如何將html表綁定到「foreach:items」將爲VM中的每個行分配一個關聯項,但我的應用中的情況是該表不應該由knockout動態創建但由jqgrid。該表只能顯示總票證集合中的X個頁面中的1個。我不確定是否已經足夠好地解釋了我的用例,但是您是否發現有任何jqgrid構建html表的矛盾,但是在創建時爲每個行添加複選框?這可能是一個糟糕的主意,使用淘汰賽只是我的應用程序的有限部分.. –