Select 元素未使用 Knockout 正确更新

Select element not updating correctly with Knockout

背景

我有一种情况,我想要一些下拉菜单,这些菜单可以根据可用的内容更改选项。我已经设法简化了这段代码并用下面的代码复制了这个问题。

在此示例中,我有 5 种可用颜色,我想选择其中四种。如果我 select 一个,那么我希望它在其他菜单中不可用。

问题

下拉菜单只是一种工作。根据可用的选项,显示的选项似乎是有效的,但有时当 selecting 一个条目时,它不会允许它,直到我第二次选择。此外,正如下面的注释代码所示,lodash _.sortBy 似乎完全破坏了功能。

HTML

<div data-bind="foreach:colorChoices">
  <select data-bind="options: localAvailableOptions, optionsCaption: 'Select...', optionsText: function(currentValue) {return 'Color ID ' + currentValue;}, value: id"></select>
</div>

Javascript

function appModel() {
    var self = this;
    self.colorIds = [1, 2, 3, 4, 5];
    self.colorChoices = ko.observableArray();

    self.selectedColorIds = ko.computed(function() {
        return _(self.colorChoices())
            .filter(function(item) {
                return item.id()
            })
            .map(function(item) {
                return item.id()
            })
            .value();
    });

    self.availableColorIds = ko.computed(function() {
        return _.difference(self.colorIds, self.selectedColorIds());
    });

    self.colorChoices.push(new colorChoice(self));
    self.colorChoices.push(new colorChoice(self));
    self.colorChoices.push(new colorChoice(self));
    self.colorChoices.push(new colorChoice(self));
}

function colorChoice(parent) {
    var self = this;
    self.id = ko.observable();
    self.localAvailableOptions = ko.computed(function() {
        //clone as to not modify original array
        var availableIds = _.clone(parent.availableColorIds());
        //add own ID so dropdown menu contains matching entry
        if (self.id()) {
            availableIds.push(self.id());
        }
        //seems to break with _.sortBy
        //return _.sortBy(availableIds);
        return availableIds;
    });
}

ko.applyBindings(new appModel());

CodePen(相同代码)

https://codepen.io/anon/pen/KEKPKV

我发现了问题。

if (self.id()) {
    availableIds.push(self.id());
}

这缺少检查以查看它是否已经存在,这意味着可用选项包含重复值,这可能会产生未定义的行为。