如何实现多个选择列表,确保所有人都可以使用唯一值?

时间:2015-03-12 00:32:33

标签: knockout.js knockout-2.0

我需要确保选择列表中的唯一性。

我有一个可用选项列表:

var viewModel = 
{
    availableOptions : ['Bicycle','Car','Shuttle','Motorcycle','Motorcycle'],
    items : [{id:1, selectedOption: ko.observable('Car')}, 
             {id:2, selectedOption: ko.observable()}, 
             {id:3, selectedOption: ko.observable()}]
}

我想通过我的项目来预测,但确保没有两个项目可以有相同的选项:

<-- ko foreach: items -->
  <select data-bind="options: $parent.availableOptions, value: selectedOption, optionsCaption: 'Choose...'"></select>
<!-- /ko -->

关于如何成功实现此默认值的任何想法,只有剩余的选项可用于我的其他选择?

3 个答案:

答案 0 :(得分:2)

您需要computed来过滤每个select

的项目
this.availableOptions = ko.computed(function () {
    var item, option, i, j, isAvailable, result = [];
    for (i = 0; i < root.availableOptions.length; i++) {            
        option = root.availableOptions[i];
        isAvailable = true;
        for (j = 0; j < root.items.length; j++) {
            item = root.items[j];
            if (item.id !== this.id && item.selectedOption() === option) {
                isAvailable = false;
            }
        }
        if (isAvailable) {
            result.push(option);
        }
    }
    return result;
}, this, { deferEvaluation: true });   

请参阅working fiddle

已修改已添加deferEvaluation以使所有项目都依赖于所有项目

答案 1 :(得分:0)

尝试以下内容 -

selectedOption.subscribe(function (newValue) {
    var index = availableOptions.indexOf(selectedOption());
    if (index > -1) {
        availableOptions.splice(index, 1);
    }
});

答案 2 :(得分:0)

最简洁的方法当然不是首先将无用的重复数据发送到浏览器。

下一个最佳解决方案是使用数组唯一函数。大多数JS库都提供这样的功能。我没有特别使用lodash's uniq(),但你可以使用任何你喜欢的库,例如jQuery's $.unique()

var viewModel = {
    availableOptions : _.uniq(['Bicycle','Car','Shuttle','Motorcycle','Motorcycle']),
    items : [{id:1, selectedOption: ko.observable('Car')}, 
             {id:2, selectedOption: ko.observable()}, 
             {id:3, selectedOption: ko.observable()}]
};

一般情况下,我建议您为视图模型使用一个类,以便在构建时可以进行某种处理。对视图模型使用对象文字仅适用于最简单的情况。

例如像这样。

function ViewModel(data) {
    var self = this, i;

    self.availableOptions: ko.observableArray(_.uniq(data.availableOptions));
    self.items = ko.observableArray();

    for(i = 1; i <= data.itemCount; i++) {
        self.items.push({id:i, selectedOption: ko.observable()});
    }
}

var viewModel = new ViewModel({
    availableOptions: ['Bicycle','Car','Shuttle','Motorcycle','Motorcycle'],
    itemCount: 3
});
ko.applyBindings(viewModel);