依赖性跟踪(Dependency Tracking)

优质
小牛编辑
138浏览
2023-12-01

KnockoutJs会在值更新时自动跟踪依赖项。 它有一个称为dependency tracker (ko.dependencyDetection)的对象,它充当了双方之间用于订阅依赖关系的中间件。

以下是依赖性跟踪的算法。

依赖追踪

Step 1 - 每当您声明一个计算的observable时,KO立即调用其求值函数来获取其初始值。

Step 2 - 订阅被设置为评估者读取的任何可观察对象。 在应用程序中,处理不再使用的旧订阅。

Step 3 - KO最终通知更新的计算的observable。

Example

<!DOCTYPE html>
<html>
   <head>
      <title>KnockoutJS How Dependency Tracking Works</title>
      <!-- CDN's-->
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js"
         type = "text/javascript"></script>
   </head>
   <body>
      <div>
         <form data-bind = "submit: addFruits">
            <b>Add Fruits:</b>
            <input data-bind = 'value: fruitToAdd, valueUpdate: "afterkeydown"'/>
            <button type = "submit" data-bind = "enable: fruitToAdd().length > 0">Add</button>
            <p><b>Your fruits list:</b></p>
            <select multiple = "multiple" width = "50" data-bind = "options: fruits"> </select>
         </form>
      </div>
      <script>
         var Addfruit = function(fruits) {
            this.fruits = ko.observableArray(fruits);
            this.fruitToAdd = ko.observable("");
            this.addFruits = function() {
               if (this.fruitToAdd() != "") {
                  this.fruits.push(this.fruitToAdd());   // Adds a fruit
                  this.fruitToAdd("");                   // Clears the text box
               }
            }.bind(this);                                // "this" is the view model
         };
         ko.applyBindings(new Addfruit(["Apple", "Orange", "Banana"]));
      </script>
   </body>
</html>

Output

让我们执行以下步骤来查看上述代码的工作原理 -

  • 将以上代码保存在dependency_tracking.htm文件中。

  • 在浏览器中打开此HTML文件。

  • 输入任何水果名称,然后单击“添加”按钮。

使用Peek控制依赖关系

通过使用peek函数,可以在不创建依赖项的情况下访问Computed Observable。 它通过更新计算属性来控制Observable。

Example

<!DOCTYPE html>
<html>
   <head>
      <title>KnockoutJs Controlling Dependencies Using Peek</title>
      <!-- CDN's-->
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js"
         type = "text/javascript"></script>
   </head>
   <body>
      <div class = "logblock">
         <h3>Computed Log</h3>
         <pre class = "log" data-bind = "html: computedLog"></pre>
      </div>
      <script>
         function AppData() {
            this.firstName = ko.observable('John');
            this.lastName = ko.observable('Burns');
            this.computedLog = ko.observable('Log: ');
            this.fullName = ko.computed(function () {
               var value = this.firstName() + " " + this.lastName();
               this.computedLog(this.computedLog.peek() + value + '; <br/>');
               return value;
            }, this);
            this.step = ko.observable(0);
            this.next = function () {
               this.step(this.step() === 2 ? 0 : this.step()+1);
            };
         };
         ko.applyBindings(new AppData());
      </script>
   </body>
</html>

Output

让我们执行以下步骤来查看上述代码的工作原理 -

  • 将以上代码保存在dependency_tracking_peek.htm文件中。

  • 在浏览器中打开此HTML文件。

观察 (Observations)

忽略计算依赖关系中的依赖关系

ko.ignoreDependencies函数有助于忽略您不希望在计算的依赖项中跟踪的那些依赖项。 以下是它的语法。

ko.ignoreDependencies( callback, callbackTarget, callbackArgs );

为什么循环依赖没有意义

如果KO正在评估Computed Observable,那么它将不会重新启动对依赖Computed Observable的评估。 因此,在依赖链中包含循环是没有意义的。