使用油门时可观察到的淘汰赛不会触发

Knockout observable not triggering when using throttle

我有以下内容:

self.periodicallySave = ko.computed(function () {
    if (self.optionA() || self.optionB() || self.optionC()) {
        self.saveOptions();
    }
}).extend({ throttle: 1000 });

我正在使用这个计算器在文本字段更新时定期保存它们。这些文本字段是 textareas,看起来像这样:

    <textarea rows="2" data-bind="textInput: optionA"></textarea>

optionA 除外,它是 select

            <select data-bind="value: optionA">
                <option>Foo</option>
                <option>Bar</option>
            </select>

出于某种原因,只有 OptionA 触发了我计算的可观察对象;改变其他的没有效果。我是否误解了计算的可观察量是如何工作的?我的期望是,如果这些可观察量中的任何一个发生变化,该函数就会被触发。

更新:

如果我使用 + 而不是 ||,它会按预期工作。奇怪的是 OR 似乎停止了可观察链;特别是因为 optionA 是一个 select,它只能包含两个值之一。删除 optionA 也会产生预期的结果。

我认为这与 knockout 为计算函数设置变化跟踪依赖关系的方式有关。您的 3 个选项 observables 都在 IF 语句中,因此如果第一个选项开始时为真,则后两个条件会短路并且不会被评估。由于未对它们进行评估,因此敲除永远不会绑定到它们。

在我看来,以这种方式使用的计算可观察值有点危险,因为它通常会产生意想不到的副作用。你可以很容易地 "fix" 这种行为,方法是在检查它们的值之前首先将可观察对象解包到变量中:

self.periodicallySave = ko.computed(function () {
    var a = self.optionA();
    var b = self.optionB();
    var c = self.optionC();

    if (self.optionA() || self.optionB() || self.optionC()) {
        self.saveOptions();
    }
  }).extend({ throttle: 1000 });

但我认为为每个 observable 设置订阅可能更简洁(虽然不够简洁)。