Heim > Web-Frontend > js-Tutorial > Hauptteil

Dirty Checking in AngularJS verstehen

青灯夜游
Freigeben: 2021-02-01 11:45:24
nach vorne
1937 Leute haben es durchsucht

Dirty Checking in AngularJS verstehen

Verwandte Empfehlungen: „AngularJS-Tutorial“

AngularJS implementiert die bidirektionale Bindung, die sich von vues defineProperty unterscheidet. Hier ist eine Zusammenfassung von

Angular.js-Einführung

    AngularJs ist ein MVVM-Framework und Scope ist eine Datensammlung von VM-Komponenten.
  • AngularJs verwendet Anweisungen, um das Verhalten von VM zu deklarieren den Bereich und die neuesten Eigenschaften aktualisieren. Die bidirektionale Bindung von UI
  • AngularJs: Zum Beispiel: Eine besteht darin, den Attributwert $scope an die HTML-Struktur zu binden. Die andere besteht darin, den Wert des $scope-Attributs an die HTML-Struktur zu binden. Die andere besteht darin, den Wert des $scope-Attributs an die Schnittstelle zu binden. Vorgänge wie Klicken, Tippen und Auswählen lösen automatisch Änderungen im $scope-Attribut aus Schnittstelle kann sich auch entsprechend ändern)
  • Änderungen von Bereichsattributen überwachen: Dirty Check
Dirty Check

    angular überwacht überhaupt keine Datenänderungen, durchläuft aber zum richtigen Zeitpunkt ($watch) alle $scopes beginnend mit $rootScope ,
  • Überprüfen Sie, ob sich die Attributwerte darauf geändert haben. Wenn es Änderungen gibt, verwenden Sie eine schmutzige Variable, um sie als wahr aufzuzeichnen, und wiederholen Sie den Vorgang. Traverse ($digest),
  • usw., bis a Wenn eine bestimmte Durchquerung abgeschlossen ist und sich die Attributwerte dieser $scopes nicht geändert haben, endet die Durchquerung.
  • Da eine Dirty-Variable als Datensatz verwendet wird, wird sie als Dirty-Checking-Mechanismus bezeichnet.
Kurz gesagt: Wenn der Bereich erstellt wird, analysiert Angular die Vorlage, ermittelt die Bindungswerte und Ereignisaufrufe und bindet sie mit $watch.

$scope.$watch(string|function, listener, objectEquality, prettyPrintExpression)
// string: 验证值或者function执行后return的string
// listener: 如果验证值不同,则执行该监听函数
// objectEquality:执行深检查
Nach dem Login kopieren
    Nach Abschluss der Bindung wird dies der Fall sein automatisch erkannt werden Wenn sich diese Attribute ändern, wird $watch ausgeführt und die entsprechenden Informationen werden an einen $$watchers innerhalb von Angular gebunden.
  • Es handelt sich um eine Warteschlange (Array), und wenn $digest ausgelöst wird, durchläuft Angular dieses Array.
  • und verwenden Sie eine Dirty-Variable, um aufzuzeichnen, ob sich die in $$watchers aufgezeichneten $scope-Attribute geändert haben.
Der nächste Prozess:

  • Beurteilen Sie, ob Dirty wahr ist, wird $digest nicht ausgeführt . Rekursion. (Dirty ist standardmäßig true)

  • Durchlaufen Sie $$watcher, nehmen Sie den alten Wert und den neuen Wert des entsprechenden Attributwerts heraus und vergleichen Sie den alten und neuen Wert gemäß objectEquality.

  • Wenn die beiden Werte unterschiedlich sind, fahren Sie mit der Ausführung fort. Wenn die beiden Werte gleich sind, setzen Sie dirty auf false.

  • Nachdem Sie alle Beobachter überprüft haben, stellen Sie Dirty auf „true“ ein und ersetzen Sie den alten Wert durch den neuen Wert.

  • Auf diese Weise wird in der nächsten Rekursionsrunde der alte Wert verwendet neuer Wert dieser Runde Rufen Sie $digest erneut auf (einfach ausgedrückt führt es zwei rekursive Durchläufe durch, um die Änderungen in den alten und neuen Werten zu überprüfen)

  • Den geänderten $scope erneut in die Schnittstelle rendern

$Apply-Trigger $digest

    Im Allgemeinen wird $digest nicht aufgerufen, um $apply aufzurufen, was intern die rekursive Durchquerung von $digest auslöst. Die internen Anweisungen von Angular kapseln $apply, z. B. ng-click, sodass im Allgemeinen kein manueller Vorgang erforderlich ist call apply
  • Apply manuell aufrufen

Manchmal muss es manuell ausgelöst werden

    function($timeout) {
      // 当我们通过on('click')的方式触发某些更新的时候,可以这样做
      $timeout(() => { // 内置语法糖 $http, $timeout已经包含了apply
        $scope.name = 'lily'
      })
      // 也可以这样做
      $element.on('click', () => {
        $scope.name = 'david'
        $scope.$apply()
      })
    }
    Nach dem Login kopieren
  • Hinweis: Während des rekursiven Prozesses darf $apply nicht manuell aufgerufen werden, z. B. in der ng-click-Funktion, z. B. in der Callback-Funktion von $watch.
Implementieren Sie abschließend einen einfachen Dirty-Check-Mechanismus
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>angularjs脏检查实现</title>
</head>
<style type="text/css">
  button {
    height: 60px;
    width: 100px;
  }

  p {
    margin-left: 20px;
  }
</style>

<body>
  <div>
    <button type="button" ng-click="increase">增加</button>
    <button type="button" ng-click="decrease">减少</button>
    数量:<span ng-bind="data">0</span>
  </div>
  <br>
</body>
<script>
  window.onload = function () {
    /**
     * 声明构造函数
     */
    function Scope() {
      this.$$watchList = []; // angular内部会声明一个数组(包含监听的对象),在digest执行时去遍历
    }

    /**
     * 属性赋值给$scope
     * 类似angular解析controller的模板,把模板中的属性解析出来,属性赋值给$scope
     */
    Scope.prototype.getNewValue = function () {
      return $scope[this.name];
    }

    /**
     * 实现监听
     */
    Scope.prototype.$watch = function (name, listener) {
      let watch = {
        name: name,
        getNewValue: this.getNewValue,
        listener: listener || function () { }
      };
      // 当作用域创建时,angular会去解析模板,$watch用来绑定监听值和监听函数
      this.$$watchList.push(watch);
    }

    /**
    * 检查dirty,循环更新scope上的最新值
    */
    Scope.prototype.$digest = function () {
      console.log(&#39;$digest&#39;);
      let dirty = true; // 默认dirty变量为true
      let checkTimes = 0;
      while (dirty) {
        dirty = this.$valScope();
        checkTimes++;
        if (checkTimes > 10 && dirty) {
          throw new Error("循环过多");
        }
      }
    }

    /**
     * 验证值是否有变化
     */
    Scope.prototype.$valScope = function () {
      let dirty;
      let list = this.$$watchList;
      for (let i = 0; i < list.length; i++) {
        let watch = list[i];
        let newValue = watch.getNewValue();
        let oldValue = watch.last || undefined;
        if (newValue !== oldValue) {
          watch.listener(newValue, oldValue);
          dirty = true; // 如果新旧值不同,则继续遍历
        } else {
          dirty = false;
        }
        watch.last = newValue;
      }
      return dirty;
    }

    /**
     * 刷新scope
     */
    Scope.prototype.$apply = function (params) {
      let list = document.querySelectorAll(&#39;[ng-bind]&#39;);
      console.log(&#39;list&#39;, list)
      for (let i = 0, l = list.length; i < l; i++) {
        let bindData = list[i].getAttribute(&#39;ng-bind&#39;);
        console.log(&#39;bindData&#39;, bindData)
        console.log(&#39;list[i]&#39;, list[i])
        list[i].innerHTML = $scope[bindData];
      }
    }

    let $scope = new Scope(); // 实例化,声明$scope对象集合
    $scope.data = 0;
    $scope.increase = function () {
      this.data++;
    };
    $scope.decrease = function () {
      this.data--;
    };

    $scope.$watch(&#39;data&#39;, function(newValue, oldValue) { // 监听
        console.log("new: " + newValue + "=========" + "old: " + oldValue);
    });


    // 手动为button按钮添加onclick事件,并为通过闭包为其绑定了全局scope对象,绑定apply方法
    // 类似angular内部实现
    function startBind() {
      let list = document.querySelectorAll(&#39;[ng-click]&#39;);
      for (let i = 0, l = list.length; i < l; i++) {
        list[i].onclick = (function (index) {
          return function () {
            let func = this.getAttribute(&#39;ng-click&#39;);
            $scope[func]($scope);
            $scope.$digest();
            $scope.$apply()
          }
        })(i)
      }
    }

    // 初始化
    startBind();
  }

</script>

</html>
Nach dem Login kopieren
Weitere Programmierkenntnisse finden Sie unter:

Programmiervideo

! !

Das obige ist der detaillierte Inhalt vonDirty Checking in AngularJS verstehen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:cnblogs.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage