淘汰匿名计算observable执行不止一次

时间:2015-02-23 16:53:54

标签: knockout.js anonymous computed-observable

最近,我在我正在开发的项目中碰到了相当奇怪的代码。以下是描述该问题的独立示例:

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

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

  1. 这是淘汰赛中的一个错误,最终会被修复吗? (所以我最好删除这个魔法,然后在更新后停止工作)
  2. 这是一种常见的种类,完全可以使用吗?
  3. 更新: 在我在项目中遇到的实际情况中,我需要维护有几行代码代替alert而没有直接引用依赖的observable,obtable的值在一些嵌入式函数调用中被改变。给出的例子非常简单。此外,两个计算的可观察量都用节流扩展器装饰,这可能是首先计算它们的唯一目的。

2 个答案:

答案 0 :(得分:1)

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

但是,您可以使用peek()方法明确指示Knockout 而不是创建依赖项:

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

请参阅"How dependency tracking works"

答案 1 :(得分:0)

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

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