【问题标题】:knockout anonymous computed observable executing more than once淘汰匿名计算 observable 执行多次
【发布时间】:2015-04-25 01:59:20
【问题描述】:

最近,我在当前正在处理的项目中遇到了相当奇怪的代码。这是描述该问题的孤立示例:

<html lang="en-US">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <input type="text" data-bind = "value: firstName">
    <input type="text" data-bind = "value: lastName">
  <br />  <br />
  <span data-bind = "text: firstName"></span>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
  <script>
    var myViewModelProto = function(){
    self = this;
    this.firstName = ko.observable("John");
    this.lastName = ko.observable("Smith");

    ko.computed(function(){
        alert(self.lastName());
    });
};

var vm = new myViewModelProto();
ko.applyBindings(vm);
</script>
</body>
</html>

anonymous 计算的 observable 中的警报不仅会在创建 viewModel 时触发,而且每次都会触发依赖的 observable(在本例中为 lastName)构造函数完成之后。在我现在维护的代码中,这用于运行特定代码以重绘绑定的 ui 小部件。 所以我的问题是:

  1. 这是最终修复的淘汰赛中的错误吗? (所以我最好在更新后停止工作之前移除这个魔法)
  2. 这是一种常见的模式并且完全可以使用吗?

更新: 在我在项目中遇到的实际情况中,我需要维护有几行代码来代替 alert,并且没有直接引用依赖的 observable,observable 的值在从计算内部进行的一些嵌套函数调用中发生了变化。给出的示例非常简化。此外,两个计算的 observables 都装饰有油门扩展器,这可能是让它们首先被计算的唯一目的。

【问题讨论】:

  • 你为什么首先创建computed
  • 您到底希望发生什么?这不是一个错误……这正是计算出的 observable 应该如何工作的。该值是在创建时计算的,并在它所依赖的其他 observables 更新时更新。
  • 我希望 anonymous 计算的 observable 在声明时只执行一次。由于无法读取它的值,因此不再执行它。我希望它在一定程度上类似于pure computed 行为。没有名字 > 没有订阅者 > 没有执行。
  • 您正在将计算的 observable 视为一个值。虽然可能是这样,但没有要求说明它必须这样做。也许将计算的视为回调函数会更容易。在匿名计算的情况下,它就像一个没有返回值的回调函数,而命名计算类似于一个返回值的回调函数。

标签: knockout.js anonymous computed-observable


【解决方案1】:

当一个函数(包括computed 函数)正在读取某个可观察对象的值时,Knockout 会自动在两者之间创建一个依赖关系。一旦可观察值发生变化,所有相关函数都将重新计算。

但是,您可以显式指示 Knockout 使用 peek() 方法创建依赖项:

ko.computed(function(){
    alert(self.lastName.peek());
});

"How dependency tracking works"

【讨论】:

  • 这是一个有效的解释为什么会发生这种情况,但问题是它是否是淘汰赛的预期(而不是副作用)效果以及是否是一个好的做法在这些函数中加入一些逻辑。就我个人而言,我不希望在构造函数完成后有一个匿名且不可读的计算 observable 来执行它的代码。
  • 当然是有意的。许多人利用这种行为来检测整个模型中的深层变化,方法是在 computed 中调用 ko.toJSON(),以创建该依赖关系并订阅更改。
【解决方案2】:

当然,每次当函数内部使用的任何 observable 的值发生变化时,计算函数都会调用。

http://knockoutjs.com/documentation/computedObservables.html

【讨论】:

    猜你喜欢
    • 2019-06-02
    • 1970-01-01
    • 2016-07-21
    • 2020-05-30
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    • 2013-04-10
    • 1970-01-01
    相关资源
    最近更新 更多