2

我正在研究一个问题/答案模型,并且我有多个包含相同数据的下拉列表(如果您愿意,可以选择一组答案)。这里的业务逻辑是,一旦有人选择了一个问题的答案,该答案只能使用一次,并且不能用于其他问题。

因此,我找到了一种将所有下拉列表绑定到包含我的答案的单个 observableArray 的方法,以便下拉列表都包含相同的选项。我想做的是订阅一个下拉列表的当前值(在许多下拉列表中),并从与它们关联的所有其他下拉列表中删除选定的值。使用 Knockout,我已经能够订阅一个回调函数来响应我视图中不断变化的值。

在我的回调函数中,我发现使用 observableArray 的remove方法从我的 observableArray 中删除答案是可行的,但不幸的是它会从所有下拉列表中删除当前选择的答案 - 包括选定的答案!我试过用 push 命令把它放回去,但这也会导致问题。我似乎无法以我想要的方式隔离更新。

以前有没有人使用 Knockout 实现过类似的东西?任何帮助或建议将不胜感激。

4

2 回答 2

4

因为如果您从中删除一个项目,您将绑定到一个选项数组,那么选项绑定将正确反映这一点。您可以为每个要绑定的选择框使用计算来创建独立的虚拟列表。

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

http://jsfiddle.net/madcapnmckay/6uWEu/2/

编辑

这是上述工作的方式。您需要将每个选择绑定到它自己的可观察对象,以便在您选择第一个值时可以更新其他值。如果您只是简单地绑定到同一个列表并在每次选择一个值时从中删除,那么您也将删除您刚刚选择的值,KO 会相应地更新选择元素,它将被完全破坏。

上面的代码通过依次过滤每个来解决这个问题。我将每个下拉菜单重定向到它自己的计算 observable。这些计算出的 observables 只是调用一个过滤器函数,该函数循环遍历 values 数组并过滤掉任何不是当前选定值的已选择值。

因此,如果我们从所有未选择的第一个选择开始,“选项 1”选择了 values1,计算的 values2 和 values3 将由 KO 自动重新计算。以 values1 为例,它将调用

self.remaining("option 1");

values2 * values3 也将调用剩余但未定义,因为它们尚未被选择。

self.remaining(null);

values 数组被过滤为尚未选择且不是当前值的选项。因此,第一次调用剩余将导致[ "option 1", "option 2", "option 3"]. 对剩余的第二次和第三次调用将导致[ "option 2", "option 3"].

如果取消选择第一个选择,则执行相同的操作并返回所有选项。

希望这可以帮助。

于 2012-05-15T16:23:57.897 回答
0

当我不得不做类似的事情时,我IsSet在项目上有一个属性,以及两个计算的 observables,一个用于设置它的值,一个用于未设置它的值:

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(); });
    });
};
于 2012-05-15T19:47:33.413 回答