2012-02-23 62 views
2

我有一個模型,看起來像這樣(不是實際的代碼,所以不介意可能mistyping)。與對象使用KnockoutJS下拉初始選擇

model = function(option, items) { 
    self = this; 
    self.options = options; 
    self.items = ko.mapping.fromJS(items); 
} 

對象,人們可以從一個下拉列表中選擇的options coantains名單。 items還包含一個對象列表,其中每個對象都有一個相同的對象,如選項列表中的對象。

然後,我會對項目列表進行foreach,並在每行上顯示一個下拉框。 我在這裏需要項目列表中當前項目中的對象是選定的選項。當我但是沒有設置一個選項值,但只嘗試匹配整個對象時,它不起作用...然後,我的觀察值工作正常,整個對象的所有訂閱字段都使用新選擇更新。然而,我得到了如下的optionValue和Id的初始選擇。

<select data-bind="options: $parent.options, optionsValue:'Id', optionsText: 'Name', value: item.Id"></select> 

我現在的問題是,只有綁定ID的元素被更新?我需要更新當前項目的所有屬性,即使它僅僅是當我更改下拉列表中的某些內容時現在發生更改的Id。

我該怎麼做?

+5

你可能想重現上jsfiddle.net – 2012-02-23 21:48:09

回答

6

所以我承擔這一點是以下幾點。

  • 你有一組 '選項'。每個選項都有一些屬性和一個ID
  • 你有一組「項目」,其中每個項目都有包含對象,等於內選擇對象一個一個屬性。所以每個'項目'有一個選擇'選項'。

與c#和其他高級環境不同,javascript沒有內置的平等概念。當您執行類似objA == objB時,它將檢查參考是否相等(對於諸如數字和字符串的基本類型不是這樣),即兩個變量實際上引用同一個對象。例如,在.NET中,一個類可以實現IEquatable<T>(和一個操作符重載),這樣objA == objB會導致一些自定義的比較,這將決定兩個不同的對象是否可以被認爲是相等的。

因此,與淘汰賽工作時和下拉,這樣要記住的是,爲了淘汰賽匹配你必須確保比較的對象確實是相同是非常重要的。

就你而言,我已經調整了一下你的模型。我假設項目的選項屬性被稱爲SelectedOption

function model(options, items) { 
    self = this; 
    self.options = options; 
    self.items = ko.mapping.fromJS(items); 

    // Loop over each of the items and swap out the server-side provided option object 
    // with the corresponding option from the options parameter. 
    ko.utils.arrayForEach(self.items(), function(item) { 
     item.SelectedOption = ko.observable(
      ko.utils.arrayFirst(self.options, function(option) { return option.Id == item.SelectedOption.Id(); }) 
     ); 
    }); 
} 

由於您使用ko.mapping我假設的選項和項目參數爲純提供的JavaScript對象以某種方式(阿賈克斯,內聯JS)。

opts = [ 
    { Id: 1, Name: "Option 1" }, 
    { Id: 2, Name: "Option 2" }, 
    { Id: 3, Name: "Option 3" } 
]; 

var items = [ 
    { Id: 1, Name: "Item 1", SelectedOption: { Id: 1, Name: "Option 1" } }, 
    { Id: 2, Name: "Item 2", SelectedOption: { Id: 2, Name: "Option 2" } }, 
    { Id: 3, Name: "Item 3", SelectedOption: { Id: 3, Name: "Option 3" } } 
]; 

var viewModel = new model(opts, items); 

由於包含在每個項目的SelectedOption參數的選項是完全相同作爲選項屬性淘汰賽的那些現在能夠比較它們是否相等,你可以用它在你的綁定是這樣:

<div data-bind="foreach: items"> 
    <select data-bind="options: $parent.options, optionsText: 'Name', value: SelectedOption"></select> 
</div> 

測試它在的jsfiddle:http://jsfiddle.net/niik/HDsKC/

+0

完善的問題!謝謝! – Riri 2012-02-26 17:09:49

+0

該問題的絕佳解決方案。 +1 – Darbio 2012-11-29 03:39:23