如何实现多个 select 列表以确保只有唯一值可供所有人使用?
How do I implement multiple select lists ensuring only unique values are available to all?
我需要确保我的 select 列表中的唯一性。
我有可用选项列表:
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 -->
关于如何在默认值不变的情况下成功实现此目的的任何想法,并且只有其余选项可供我的其他 select 使用?
试试下面的方法 -
selectedOption.subscribe(function (newValue) {
var index = availableOptions.indexOf(selectedOption());
if (index > -1) {
availableOptions.splice(index, 1);
}
});
最干净的方法当然是首先不向浏览器发送无用的重复数据。
下一个最佳解决方案是使用数组唯一函数。大多数 JS 库都提供这样的功能。没有特别的原因,我正在使用 lodash's uniq()
but you can use any library you like, for example 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()}]
};
一般来说,我建议您对视图模型使用 class,这样您就可以在构建它时进行某种处理。将对象文字用于视图模型仅适用于最简单的情况。
比如这样。
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);
您需要 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 });
已编辑 添加了 deferEvaluation
以使所有项都依赖于所有项
我需要确保我的 select 列表中的唯一性。
我有可用选项列表:
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 -->
关于如何在默认值不变的情况下成功实现此目的的任何想法,并且只有其余选项可供我的其他 select 使用?
试试下面的方法 -
selectedOption.subscribe(function (newValue) {
var index = availableOptions.indexOf(selectedOption());
if (index > -1) {
availableOptions.splice(index, 1);
}
});
最干净的方法当然是首先不向浏览器发送无用的重复数据。
下一个最佳解决方案是使用数组唯一函数。大多数 JS 库都提供这样的功能。没有特别的原因,我正在使用 lodash's uniq()
but you can use any library you like, for example 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()}]
};
一般来说,我建议您对视图模型使用 class,这样您就可以在构建它时进行某种处理。将对象文字用于视图模型仅适用于最简单的情况。
比如这样。
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);
您需要 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 });
已编辑 添加了 deferEvaluation
以使所有项都依赖于所有项