2

我有一个可观察的数组,其中包含绑定到网格行中的选择下拉框的可用项目。用户可以使用下拉菜单添加更多行并在每个行中选择项目。

问题是一旦在下拉行中选择了一个项目,除了选择它的下拉列表之外,它不应该在任何其他下拉列表中可用。从数组中删除所选项目会将其从所有其他下拉列表中删除,也会从选择下拉列表中删除。

例如:如果最初可用的数组包含 [a, b, c, d, e, f]

下拉菜单 1:选中 = a;可用 [ a , c, d, f]

下拉菜单 2:选中 = b;可用 [ b , c, d, f]

下拉菜单 3:选中 = e;可用 [c, d, e , f]

我正在尝试一种 ko.computed 方法,该方法根据 availableItems 加上当前选择的值返回一个数组。但是我在让计算更新每个下拉列表时遇到了一些问题。

粗略的代码片段:

<table>
    <tbody data-bind='foreach: item'>
        <tr>
            <td>
                <select data-bind="
                    options: $root.availableItemsWithFilter,
                    event: { onchange: changedItem }">
                </select>
            </td>
        </tr>
    </tbody>
</table>

self.availableItemsFiltered = ko.computed(function () {
    var temp = self.availableItems();
    if (currentRowNumber == self.selectedRow()) {
        temp.push(self.selectedItem);
    }
    return temp;
});

self.changedItem = function(item) {
    if (self.selectedItem != '')
    {
        self.availableItems.remove(item);
    }
}
4

1 回答 1

2

只是出于好奇和提醒自己淘汰赛的工作原理,我对这个问题做了另一个解决方案。

http://jsfiddle.net/rainerpl/n01fvoaq/3/

和下面的代码

HTML

<div>


<select data-bind="optionsCaption: 'Choose...', options: $root.availableOptions.filter($element), optionsText: 'name', optionsValue: 'id', event: { change: changedItem($element)}">
</select>
<div data-bind="foreach: $root.selectedOptions().slice(1)">
    <select data-bind="optionsCaption: 'Choose...', options: $root.availableOptions.filter($element), optionsText: 'name', optionsValue: 'id', event: { change: $root.changedItem($element)}">
</select><br>

</div>
</div>

和 Javascript

window.model = new function() {
    var _model = this;
    this.availableOptions = ko.observableArray([
        {name: "option1", id: 1}, 
        {name: "option2", id: 2}, 
        {name: "option3", id: 3}, 
        {name: "option4", id: 4}, 
    ]);
        this.changedItem = function( item, val ) {
            var ind;
            if ( !item ) {return;}
            if ( item.previous_id ) {
            ind =  _model.selectedOptions().indexOf(item.previous_id);

        if (ind !== (-1) ) {_model.selectedOptions.splice(ind, 1);}
            }
            ind = _model.selectedOptions().indexOf(item.value);
            if ( ind == (-1) ) {_model.selectedOptions.push(item.value);}
            item.previous_id = item.value;
        }
        this.selectedOptions = ko.observableArray([]);
        _model.availableOptions.filter = function(elem) {
            return _model.availableOptions().filter(function(item) {
                var ind = _model.selectedOptions().indexOf(item.id.toString() );
                if ( elem.value == item.id ) {return true;}
                return ind == (-1);
            });
        };
}();
ko.applyBindings(model);
于 2015-05-13T05:14:24.403 回答