【问题标题】:Knockout.js computed write not firing mutation event when underling data isn't observed当未观察到底层数据时,Knockout.js 计算写入未触发突变事件
【发布时间】:2013-02-09 06:44:10
【问题描述】:

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

我所说的一个例子:

<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/

【问题讨论】:

    标签: javascript web-applications mvvm web knockout.js


    【解决方案1】:

    这与how dependency tracking works有关。

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

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

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

    Object.observe 将解决这个问题。

    【讨论】:

    • 我得到了那么多。它解释了为什么代码不起作用,但没有解释为什么以这种方式实现。对不起,如果我很密集。为什么我们不想在相同的计算值被更改时触发突变事件。这样做似乎完全合乎逻辑。
    • @mikerobertking 因为 KO 没有看到不可观察对象(名字或姓氏)的变化,并且它认为 fullName 也没有改变;)
    猜你喜欢
    • 2021-09-24
    • 2016-11-01
    • 2013-02-07
    • 1970-01-01
    • 2021-03-07
    • 1970-01-01
    • 2011-04-24
    • 1970-01-01
    • 2015-06-11
    相关资源
    最近更新 更多