4

我正在尝试创建一个包含两个下拉列的数据绑定表。但是,右侧下拉菜单中可用的选项取决于左侧下拉菜单中选择的内容。例如,imagineDropdownA有一个州列表,并且DropdownB有一个该州的城市列表。我的模板如下所示:

<!-- 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 定义依赖下拉列表的示例,但是这些示例假设您只有一个源下拉列表(例如 State)。就我而言,我需要在网格中创建任意数量的下拉对。有没有人有一个如何做到这一点的例子?

4

2 回答 2

6

我会将城市放在state对象上,然后将它们作为computed行项目跟踪,因为它将具有用于状态选择的 oberable。这是一个小提琴

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;
    });
于 2013-02-26T00:26:22.410 回答
1

我想到了两个解决方案:

  • 订阅DropdownAviewmodel 中的 observableArray 并替换 observableArray 中的城市范围,DropdownB 只要它发生变化
  • 使用可观察的数据上下文:使用可观察的作为选项源,以便您在需要时也可以更改它。像第一个一样订阅并DropdownA在更改时替换整个城市集合

我会选择第二个,因为那更干净。

这是我为您制作的 jsfiddle 示例。

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());
于 2013-02-26T00:17:01.610 回答