Knockout.js计算了当下属数据为't观察到

Knockout.js computed write not firing mutation event when underling data isn't observed

本文关键字:观察 数据 计算 js 算了 Knockout      更新时间:2023-09-26

我一直在试图确定为什么计算值上的写函数不会自动触发突变事件,至少不会在其自身上触发突变事件。

我所说的一个例子:

<span data-bind="text: fullName"></span>
<input data-bind="value: fullName"/>

使用以下JavaScript。

<script type="text/javascript">
function MyViewModel() {
    this.firstName = 'first';
    this.lastName = 'last';
    this.fullName = ko.computed({
        read: function () {
            return this.firstName + " " + this.lastName;
        },
        write: function (value) {
            var lastSpacePos = value.lastIndexOf(" ");
            if (lastSpacePos > 0) { // Ignore values with no space character
                this.firstName = value.substring(0, lastSpacePos); // Update "firstName"
                this.lastName = value.substring(lastSpacePos + 1); // Update "lastName"
            }
        },
        owner: this
    });
}
ko.applyBindings(new MyViewModel());

我理解这种情况的发生是因为firstName和lastName是不可观测的,但我不明白为什么。即使下属数据在其他地方单独使用,至少任何使用fullName的字段都会更新,这似乎是合乎逻辑的。

所以我的问题具体是:

  1. 为什么会发生这种情况
  2. 如果你不想观察firstName或lastName,你怎么能避开它

http://jsfiddle.net/TWR6Y/

这与依赖项跟踪的工作方式有关

  1. 每当您声明一个计算的可观察对象时,KO会立即调用其evaluator函数以获取其初始值
  2. 而你的评估者函数正在运行,KO会记录任何可观测值(或计算值可观察性(的值
  3. 当您评估器完成后,KO为每个你接触过的可观察性(或计算的可观察性(。这个订阅回调设置为使您的计算器再次运行,将整个过程循环回到步骤1(处理任何旧的不再适用的订阅(
  4. KO通知任何订阅者您计算的可观测值的新值

由于firstNamelastName不是ko.observable的,KO不会将它们添加到日志中(请参见步骤2(。因此,您的代码(没有可观察性(将无法工作。

进一步总结答案。在这个问题和更新时,Javascript无法为本机类型提供事件处理。Knockout通过处理数据来创建一个拦截点,从而可以看到对象的突变,从而克服了这个问题。在不拦截的情况下观察本地人的唯一方法是扫描,这是低效的。

这个问题将通过对象来克服。观察.