Knockout JS声明绑定如何在内部工作

时间:2016-05-31 04:34:41

标签: javascript knockout.js data-binding

我编写了一个代码,点击按钮显示或隐藏特定的div。代码位于this fiddle。 代码工作正常,但我怀疑的是当我在按钮点击时更改可观察ab的值时,那么toShow方法如何被调用?

当我的“testViewModel”发生变化时,是否会调用它? 我何时必须在()内使用data-bind

HTML代码:

<button data-bind="click: $root.changeValue">Click Me!</button>
 <div data-bind="foreach: products">
   <div data-bind="visible: $root.toShow()">
     <div data-bind="text: name"></div>
     <div data-bind="text: age"></div>
     <div data-bind="text: gender"></div>
   </div>
</div>

Javascript代码:

function testViewModel(){
   var self = this;
   self.a = ko.observable(0);
   self.b = ko.observable(0);
   var prod = [];
   for(var item in products){
     prod.push(new productItem(products[item]));
   }
   self.products = ko.observableArray(prod);
   self.changeValue = function(){
     self.a(self.a()+1);
     self.b(self.b()+1);
   }
   self.toShow = function(){
    if(self.a() % 2 === 0){
      return true;
    }
    else{
      return false;
    }
   }
 }

 function productItem(product){
   var self = this;
   self.name = ko.observable(product.name);
   self.age = ko.observable(product.age);
   self.gender = ko.observable(product.gender);
 }

 var products = [
 {
   name: 'A',
   age: 25,
   gender: 'Male'
 },
 {
   name: 'B',
   age: 27,
   gender: 'Female'
 },
 {
   name: 'C',
   age: 53,
   gender: 'Female'
 },
 {
   name: 'D',
   age: 54,
   gender: 'Male'
 }
]

ko.applyBindings(new testViewModel());

2 个答案:

答案 0 :(得分:2)

第一个问题,转述:

 <div data-bind="visible: $root.toShow()">...</div>
     
 self.a = ko.observable(0);
 self.b = ko.observable(0);
 self.toShow = function(){
  if(self.a() % 2 === 0){
    return true;
  }
  else{
    return false;
  }
 }
     

...当我在按钮点击时更改可观察的ab的值时,那么toShow方法如何被调用?

每当你在视图中有任何有效的数据绑定表达式时,Knockout将在第一次评估时注册一个依赖树,以跟踪哪个observable(包括可观察数组等)影响data-bind表达式的值。它的作用是绑定到普通的可观察对象,但也用于你所拥有的函数。

这意味着data-bind="visible: $root.toShow()会让Knockout在第一次评估时看到它依赖于a(但{em> not on b!),并且只要a 1}}更改它会重新评估visible绑定。

第二个问题

  

...我何时必须在数据绑定中使用()

这已经是asked before,虽然目前恕我直言的答案还不完整。知道这两件事:

  1. 一个observable是一个函数,并且在没有参数的情况下调用它获取它的当前值。
  2. 淘汰赛#&#34;神奇地&#34;如果它将可观察的名称视为数据绑定表达式中的唯一内容,则添加这些括号。
  3. 因此,在数据绑定中执行myObservable() 始终是安全且可选的,并且您可以有时(例如,当可观察的名称时)是表达式中唯一的一点)留下括号。

    <强> P.S

    您的问题标题询问&#34;内部如何运作&#34;,请注意Knockout为open source,您可以自己查看e.g. the expression rewriting

答案 1 :(得分:0)

在您的示例中,当视图将呈现时,toShow将仅被触发一次。要使淘汰赛跟踪依赖关系,你必须将其作为计算

<code>
self.toShow = ko.computed(function(){
    var x = self.a();
    if(x % 2 === 0){
      return true;
    }
    else{
      return false;
    }
});
</code>

请注意我在if语句之前得到值observable - 这是为了确保knockout始终跟踪此计算中的此依赖项。因为在您的示例中,如果它转到else分支,则不会再依赖于。

至于第二个问题:计算和观察不需要括号。简单的功能必须有它们。