如何使用基本KO可观察数组来更新绑定到选择选项下拉列表的多个计算可观察数组

时间:2015-05-13 03:08:03

标签: javascript arrays knockout.js drop-down-menu computed-observable

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

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

例如:如果最初可用的数组包含[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 PLUS返回当前所选值的数组。但我有一些问题让计算更新每个下拉列表。

粗略的代码剪辑:

<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);
    }
}

1 个答案:

答案 0 :(得分: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);