Javascript 淘汰JS:从其他相同下拉列表中删除选定值
我正在研究一个问答模型,我有多个下拉列表,其中包含相同的数据(答案库,如果你愿意的话)。这里的业务逻辑是,一旦有人选择了一个问题的答案,该答案只能使用一次,而不能用于其他问题 因此,我找到了一种方法,可以将所有下拉列表绑定到包含答案的单个observableArray,以便所有下拉列表都包含相同的选项。我想做的是订阅一个下拉列表的当前值(多个下拉列表中的一个),并从与之相关的所有其他下拉列表中删除所选值。使用Knockout,我已经能够订阅一个回调函数,以适应视图中不断变化的值 在我的回调函数中,我发现使用ObservalArray的Javascript 淘汰JS:从其他相同下拉列表中删除选定值,javascript,drop-down-menu,knockout.js,Javascript,Drop Down Menu,Knockout.js,我正在研究一个问答模型,我有多个下拉列表,其中包含相同的数据(答案库,如果你愿意的话)。这里的业务逻辑是,一旦有人选择了一个问题的答案,该答案只能使用一次,而不能用于其他问题 因此,我找到了一种方法,可以将所有下拉列表绑定到包含答案的单个observableArray,以便所有下拉列表都包含相同的选项。我想做的是订阅一个下拉列表的当前值(多个下拉列表中的一个),并从与之相关的所有其他下拉列表中删除所选值。使用Knockout,我已经能够订阅一个回调函数,以适应视图中不断变化的值 在我的回调函数中
remove
方法从ObservalArray中删除答案是可行的,但不幸的是,它从所有下拉列表中删除了当前选择的答案-包括所选答案!我试着用push命令把它放回去,但这也会导致问题。我似乎无法以我想要的方式隔离更新
以前有没有人用Knockout实现过类似的东西?任何帮助或建议都将不胜感激。因为您被绑定到一系列选项,如果您从其中删除一个项目,那么选项绑定将正确反映这一点。您可以为要绑定到的每个选择框使用Computed创建独立的虚拟列表
var viewModel = function(data) {
var self = this;
this.values = ko.observableArray([ "option 1", "option 2", "option 3"]);
this.selected = [
new ko.observable(),
new ko.observable(),
new ko.observable()
]
this.remaining = function (current) {
var selected = ko.toJS(self.selected),
currentValue = ko.utils.unwrapObservable(current);
var result = ko.utils.arrayFilter(self.values(), function (option) {
return option == currentValue || selected.indexOf(option) === -1;
});
return result;
};
this.values1 = ko.computed(function () {
return self.remaining(self.selected[0]);
});
this.values2 = ko.computed(function () {
return self.remaining(self.selected[1]);
});
this.values3 = ko.computed(function () {
return self.remaining(self.selected[2]);
});
};
ko.applyBindings(new viewModel());
编辑
下面是上面的工作原理。您需要将每个选择绑定到它自己的可观察对象,以便在第一个选择值时可以更新其他值。如果您只是绑定到同一个列表,并在每次选择一个值时将其删除,那么您也将删除刚才选择的值,KO将相应地更新select元素,它将被完全破坏
上面的代码通过依次过滤每一个来解决这个问题。我将每一个下拉列表重定向到它自己的计算可观察值。这些计算出的观测值只需调用一个过滤函数,该函数在值数组上循环,过滤掉所有已选择的而不是当前选择的值
因此,如果我们从所有未选择的开始,第一次选择得到“选项1”,选择值1,计算出的值2和值3将由KO自动重新计算。以值1为例,它将调用
self.remaining("option 1");
values2*values3还将调用剩余但未定义的,因为它们尚未被选择
self.remaining(null);
“值”数组将过滤为尚未选择且不是当前值的选项。因此,第一次调用remaining将导致[“选项1”、“选项2”、“选项3”]
。第二次和第三次调用剩余的将导致[“选项2”,“选项3”]
如果取消选择第一个选项,将执行相同的操作,并返回所有选项
希望这能有所帮助。因为您绑定到一个选项数组,如果您从其中删除了一个项目,那么选项绑定将正确反映这一点。您可以为要绑定到的每个选择框使用Computed创建独立的虚拟列表
var viewModel = function(data) {
var self = this;
this.values = ko.observableArray([ "option 1", "option 2", "option 3"]);
this.selected = [
new ko.observable(),
new ko.observable(),
new ko.observable()
]
this.remaining = function (current) {
var selected = ko.toJS(self.selected),
currentValue = ko.utils.unwrapObservable(current);
var result = ko.utils.arrayFilter(self.values(), function (option) {
return option == currentValue || selected.indexOf(option) === -1;
});
return result;
};
this.values1 = ko.computed(function () {
return self.remaining(self.selected[0]);
});
this.values2 = ko.computed(function () {
return self.remaining(self.selected[1]);
});
this.values3 = ko.computed(function () {
return self.remaining(self.selected[2]);
});
};
ko.applyBindings(new viewModel());
编辑
下面是上面的工作原理。您需要将每个选择绑定到它自己的可观察对象,以便在第一个选择值时可以更新其他值。如果您只是绑定到同一个列表,并在每次选择一个值时将其删除,那么您也将删除刚才选择的值,KO将相应地更新select元素,它将被完全破坏
上面的代码通过依次过滤每一个来解决这个问题。我将每一个下拉列表重定向到它自己的计算可观察值。这些计算出的观测值只需调用一个过滤函数,该函数在值数组上循环,过滤掉所有已选择的而不是当前选择的值
因此,如果我们从所有未选择的开始,第一次选择得到“选项1”,选择值1,计算出的值2和值3将由KO自动重新计算。以值1为例,它将调用
self.remaining("option 1");
values2*values3还将调用剩余但未定义的,因为它们尚未被选择
self.remaining(null);
“值”数组将过滤为尚未选择且不是当前值的选项。因此,第一次调用remaining将导致[“选项1”、“选项2”、“选项3”]
。第二次和第三次调用剩余的将导致[“选项2”,“选项3”]
如果取消选择第一个选项,将执行相同的操作,并返回所有选项
希望这能有所帮助。当我不得不做类似的事情时,我在项目上有一个
IsSet
属性,还有两个计算的可观察值,一个用于设置的值,另一个用于未设置的值:
var ViewModel = function(data) {
this.self = this;
self.originalList = ko.observableArray(data.list);
self.selectedItems = ko.computed(function() {
return ko.utils.arrayFilter(function(item) { return item.IsSet(); });
});
self.unselectedItems = ko.computed(function() {
return ko.utils.arrayFilter(function(item) { return !item.IsSet(); });
});
};
当我不得不做类似的事情时,我在项目上有一个
IsSet
属性,以及两个计算的可观察值,一个用于设置它的值,另一个用于未设置它的值:
var ViewModel = function(data) {
this.self = this;
self.originalList = ko.observableArray(data.list);
self.selectedItems = ko.computed(function() {
return ko.utils.arrayFilter(function(item) { return item.IsSet(); });
});
self.unselectedItems = ko.computed(function() {
return ko.utils.arrayFilter(function(item) { return !item.IsSet(); });
});
};
这看起来很有希望!谢谢你的回复。我将不得不对它进行大量的按摩,以使它适合我的框架,但我认为这是一个很好的起点。谢谢大家!@午餐317-是的,可能不太合身,但你明白了。您需要为每个下拉列表设置一个单独的过滤器,如何进行剩余的计算取决于您自己。我只是把它们放在数组中,这样我就可以懒洋洋地做indexOf了。我不想问,但我一直在破解这个代码,试图让它在我正在使用的框架内工作。你介意解释一下你的代码吗?也就是说,this.remaining函数,以及在this.selected中观察对象是如何工作的?哇,谢谢你的编辑!我没有意识到,观测值与选择值是绑定在一起的,这让我有点困惑。我想我完全明白你现在做了什么,这太棒了!不幸的是(o