Angular:手動髒檢查/$apply/$digest和監控對象/$watch

聲明:借鑑好多chm資料、視頻、PDF總結以下:html

1、$apply的引入

  • View

<div ng-app="">
        <div ng-controller="firstController">
            <input  ng-model="date"/>       
            {{date}}
        </div>
    </div>
  • 原生js函數,不能實現刷新(由於沒有實現雙向綁定(髒檢查))

var firstController = function($scope) {
    $scope.date = new Date().getSeconds();
    setInterval(function() {
        //並無觸發 髒檢查
        $scope.date = new Date().getSeconds();

    }, 1000)
}
  • 原生js函數,在變量改變外面加上$scope.apply(fun),手動實現髒檢查,實現刷新

var firstController = function($scope) {
    $scope.date = new Date().getSeconds();
    setInterval(function() {
        $scope.$apply(function() {
            $scope.date = new Date().getSeconds();
            //....會去觸發髒檢查
        })
    }, 1000)
}
  • Angular內置函數,默認已經實現髒檢查,實現刷新

var firstController = function($scope, $interval) {
    $scope.date = new Date().getSeconds();
    $interval(function() {
        $scope.date = new Date().getSeconds();
    }, 1000)
}
原生js:setInterval(fun)<==>$interval(fun) 一直循環執行
原生js:setTimeout(fun)<==>$TimeOut(fun)  執行一次
  • gif圖結果

  • 解釋

以`ng-開頭的` `事件` `指令`和默認`內置的函數`最後`都會執行髒檢查`。
   `原聲js`要實現如此功能,必須`在變量改變外面加上$scope.apply(fun)`,這樣會將這個`apply內的變量複製出一份`,`新值和舊值(備份)對比`,實現雙向綁定

2、$watch監聽一個對象

$watch(watchExpression, [listener], [objectEquality]);c++

  • 兩個參數

<div ng-app="">
        <div ng-controller="firstController">
            <input type="text" value="" ng-model="name"/><br/>
            注意:頁面加載的時候執行一次,默認1:改變次數:{{count}}
            <br/>
            注意:當次數超過5,頁面改變一次,count會+2,觸發2次
        </div>
    </div>
var firstController = function($scope) {
    $scope.name = '李可';
    $scope.count = 0;
    // 監聽一個model 當一個model每次改變時 都會觸發第2個函數
    $scope.$watch('name', function(newValue, oldValue) {
       $scope.count=$scope.count+1;//頁面加載的時候執行一次
        if ($scope.count > 5) {//當次數超過5,頁面改變一次,count會+2,觸發2次
            $scope.name = '已經大於5次了';
        }
    });
}
  • gif圖結果

  • 問題:爲何觸發2次呢?

估計要分析髒檢查的源碼了:原諒我處於菜鳥階段
問了一些人
數組


  • 三個參數 第三個爲true,表示對象內部的屬性。深深地監視

<div ng-app="">
        <div ng-controller="firstController">
            <input type="text" value="" ng-model="data.name"/>
            <input type="text" value="" ng-model="data.age"/>
            <input type="text" value="" ng-model="count2"/>
        </div>
    </div>
var firstController = function($scope) {
    $scope.data = {
        name: '李可',
        age: 18
    }
    $scope.count2 = 0;
    $scope.$watch('data', function() {
        ++$scope.count2;
        if ($scope.count2 > 3) {
            $scope.data.age = '換超過3了';
        }
    }, true)
}
++i先加後用(同一個表達式內用)
i++先用(同一個表達式內用)後加
var a=2;++a;var b=a*3;alert(b)//9    ++a;var b=a*3;是兩表達式
var c=2;c++;var d=c*3;alert(d)//9   c++;var d=c*3;是兩表達式
var e=2;f=e++;alert(f)//2       f=e++  有++表達式和=表達式   至關f=e; e=e+1
var g=2;h=++g;alert(h)//3       h=++g; 有++表達式和=表達式   至關g=g+1; h=g;
var i=2;x=++i +1;alert(x)//4    x=++i +1;  有++表達式和+表達式  至關i=i+1; x=i;
var m=2;y=m++ +1;alert(y)//3    x=i++ +1;  有++表達式和+表達式   至關y=m; m=m+1
  • gif圖結果

注意:頁面加載1次,`加1`
到臨界條件時,`加2`,`之後也加1`

延伸


有了上述方法:咱們能夠監控 對象、數組。爲了少第三個參數,具體數組操做,angular又增長
$watchCollection(obj, listener);,$watchGroup(watchExpressions, listener);app

相關文章
相關標籤/搜索