2013-02-26 34 views
4

我試圖用兩個下拉列創建一個數據綁定表。但是,右側下拉菜單中的選項取決於左側下拉菜單中的選項。例如,假設DropdownA有一個州的列表,DropdownB有一個在該州的城市列表。我的模板看起來是這樣的:使用Knockout.js在網格中創建依賴下拉列表

<!-- ko foreach: MeasurementInfoPlans --> 
<tr> 
    <td><select id="DropdownA" data-bind="options: $root.AllStates, optionsValue: 'State', optionsText: 'Name', value: StateId"></select></td> 
    <td><select id="DropdownB" data-bind="options: $root.AllCities, optionsValue: 'City', optionsText: 'Name', value: CityId"></select></td> 
</tr> 
<!-- /ko --> 

眼下,DropdownB顯示$root.AllCities每一個項目。但是,我只想要它只有顯示具有State屬性的任何值的城市DropdownA中選擇的任何值。

我已經在線找到了關於如何使用計算的observable定義依賴下拉列表的各種示例,但是這些示例假定您只有一個源下拉列表(如狀態)。在我的情況下,我需要在網格內創建任意數量的下拉。有沒有人有一個如何做到這一點的例子?

回答

6

我會把state對象上的城市,然後跟蹤它們的行項computed,因爲它有一個obserable的狀態選擇。這裏是a fiddle

HTML:

<select data-bind="options: $parent.states, 
        optionsText: 'name', 
        value: state"></select> 
<select data-bind="options: cities, value: city"></select> 

JS:

self.state = ko.observable(""); 
    self.city = ko.observable(""); 
    self.cities = ko.computed(function(){ 
     if(self.state() == "" || self.state().cities == undefined) 
      return []; 
     return self.state().cities; 
    }); 
+0

哦,這看起來很有希望!但是,我必須等到明天我回到辦公室才能嘗試。 '+ 1'現在! – 2013-02-26 01:25:39

+0

謝謝,這正是我需要的! – 2013-02-26 17:22:12

1

兩個解決方案進入我的腦海:

  • 訂閱在視圖模型DropdownA的observableArray和替換的DropdownB的observableArray城市的範圍內時,它改變
  • 使用可觀察到的DataContext:使用一個可觀察的選項來源,所以你可以在需要的時候改變它。訂閱DropdownA與第一個相同,並在其更改時替換整個城市集合

我會選擇第二個,因爲這更乾淨。

here is a jsfiddle sample我爲你製作。

HTML:

<select data-bind="options: dropdownA, value: dropdownAValue"> 
</select> 
<select data-bind="options: dropdownB"> 
</select> 

JS:

var viewModel = function() { 
    var _this = this, 
     dataSource1, 
     dataSource2; 

    dataSource1 = ["Hello"]; 
    dataSource2 = ["World"]; 

    _this.dropdownA = ko.observableArray(["A", "B"]); 
    _this.dropdownB = ko.observable(dataSource1); 
    _this.dropdownAValue = ko.observable(); 

    _this.dropdownAValue.subscribe(function() { 
     if (_this.dropdownAValue() == "A") { 
      _this.dropdownB(dataSource1); 
     } else { 
      _this.dropdownB(dataSource2); 
     } 
    }); 
}; 

ko.applyBindings(new viewModel()); 

然後可以很容易地使用這個概念在多行:http://jsfiddle.net/jGRQH/

HTML:

<table data-bind="foreach: rows"> 
    <tr> 
     <td> 
      <select data-bind="options: $root.dropdownA, value: dropdownAValue"> 
      </select> 
     </td> 
     <td> 
      <select data-bind="options: dropdownB"> 
      </select> 
     </td> 
    </tr> 
</table> 

JS:

var rowViewModel = function(dataSource1, dataSource2) { 
    var _this = this; 

    _this.dropdownB = ko.observable(dataSource1); 
    _this.dropdownAValue = ko.observable(); 

    _this.dropdownAValue.subscribe(function() { 
     if (_this.dropdownAValue() == "A") { 
      _this.dropdownB(dataSource1); 
     } else { 
      _this.dropdownB(dataSource2); 
     } 
    }); 
}; 

var mainViewModel = function() { 
    var _this = this, 
     dataSource1, 
     dataSource2, 
     addRow; 

    dataSource1 = ["Hello"]; 
    dataSource2 = ["World"]; 

    addRow = function() { 
     _this.rows().push(new rowViewModel(dataSource1, dataSource2)); 
    }; 

    _this.rows = ko.observableArray(); 

    _this.dropdownA = ko.observableArray(["A", "B"]); 

    addRow(); 
    addRow(); 
    addRow(); 
}; 

ko.applyBindings(new mainViewModel()); 
+0

你打我,而我正在擺弄= P – Tyrsius 2013-02-26 00:30:59

+0

我是在製造小提琴太:) – 2013-02-26 00:31:28

+0

從我可以告訴,這是行不通的,因爲綁定到DropdownB的每一行也會改變。 – 2013-02-26 02:26:18