2014-12-18 33 views
1

每個指令是否有一個額外的監視器? 以下是示例代碼 - http://plnkr.co/edit/Mg4Z7PUUJI0dQRNfFZ8z?p=preview 它有4個自定義指令與一次性綁定,但我有5個觀察者,應該只有1個。 爲什麼?一個指令=一個額外的觀察者?

angular.module("myApp", []) 
 
      .controller("initCtrl", function ($scope, $interval) { 
 
       $scope.dane = { 
 
        zm1: 'Directive 1 with onetime binding', 
 
        zm2: 'Directive 2 with onetime binding', 
 
        zm3: 'Directive 3 with onetime binding', 
 
        zm4: 'Directive 4 with onetime binding', 
 
       }; 
 

 
       $interval(function() { 
 
        $scope.watchers = countWatchers(); 
 
       }, 1000); 
 
      }) 
 
      .directive("myDir", function() { 
 
       return { 
 
        scope: { 
 
         ngModel: "=" 
 
        }, 
 
        require: "ngModel", 
 
        link: function (scope, element, attrs, ctrl) { 
 

 
        }, 
 
        template: "<div>{{::ngModel}}</div>" 
 
       } 
 
      }) 
 
    ; 
 
    /** 
 
    * Funkcja do zliczania watchers - max 2000 
 
    */ 
 
    (function() { 
 
     window.countWatchers = function() { 
 
      var root = angular.element(document.getElementsByTagName('body')); 
 

 
      var watchers = []; 
 

 
      var f = function (element) { 
 
       angular.forEach(['$scope', '$isolateScope'], function (scopeProperty) { 
 
        if (element.data() && element.data().hasOwnProperty(scopeProperty)) { 
 
         angular.forEach(element.data()[scopeProperty].$$watchers, function (watcher) { 
 
          watchers.push(watcher); 
 
         }); 
 
        } 
 
       }); 
 

 
       angular.forEach(element.children(), function (childElement) { 
 
        f(angular.element(childElement)); 
 
       }); 
 
      }; 
 

 
      f(root); 
 

 
      // Remove duplicate watchers 
 
      var watchersWithoutDuplicates = []; 
 
      angular.forEach(watchers, function (item) { 
 
       if (watchersWithoutDuplicates.indexOf(item) < 0) { 
 
        watchersWithoutDuplicates.push(item); 
 
       } 
 
      }); 
 
      return watchersWithoutDuplicates.length; 
 
     }; 
 
    })();
<!DOCTYPE html> 
 
<html> 
 

 
    <head> 
 
    <script data-require="[email protected]" data-semver="1.3.6" src="https://code.angularjs.org/1.3.6/angular.js"></script> 
 
    <link rel="stylesheet" href="style.css" /> 
 
    <script src="script.js"></script> 
 
    </head> 
 

 
    <body data-ng-app="myApp"> 
 
<div ng-controller="initCtrl" class="container"> 
 
    <div class="well">Watchers: {{watchers}}</div> 
 
    <my-dir ng-model="::dane.zm1"></my-dir> 
 
    <my-dir ng-model="::dane.zm2"></my-dir> 
 
    <my-dir ng-model="::dane.zm3"></my-dir> 
 
    <my-dir ng-model="::dane.zm4"></my-dir> 
 
</div> 
 
    </body> 
 

 
</html>

回答

2

我想通了。使用ng-model指令(作爲屬性)添加額外的觀察者。

結論:如果您不需要雙向綁定或需要true一次性綁定,請不要使用ng-model作爲屬性。

angular.module("myApp", []) 
 
      .controller("initCtrl", function ($scope, $interval) { 
 
       $scope.dane = { 
 
        zm1: 'Directive 1 with onetime binding', 
 
        zm2: 'Directive 2 with onetime binding', 
 
        zm3: 'Directive 3 with onetime binding', 
 
        zm4: 'Directive 4 with onetime binding' 
 
       }; 
 
       $scope.change = function() { 
 
        $scope.dane.zm1 = "Changed"; 
 
       }; 
 

 
       $interval(function() { 
 
        $scope.watchers = countWatchers(); 
 
       }, 1000); 
 
      }) 
 
      .directive("myDir", function() { 
 
       return { 
 
        scope: { 
 
         ngModel: "=" 
 
        }, 
 
        require: "ngModel", 
 
        link: function (scope, element, attrs, ctrl) { 
 

 
        }, 
 
        template: "<div>{{::ngModel}} - extra watcher due to ngModel</div>" 
 
       } 
 
      }) 
 
      .directive("myDirNgModel", function() { 
 
       return { 
 
        scope: { 
 
         ngModel: "=" 
 
        }, 
 
        require: "ngModel", 
 
        link: function (scope, element, attrs, ctrl) { 
 

 
        }, 
 
        template: "<div>{{ngModel}} - three extra watcher - ngModel, declaration, directive</div>" 
 
       } 
 
      }) 
 
      .directive("ngBindOneWay", function() { 
 
       return { 
 
        scope: { 
 
         var: "@" 
 
        }, 
 
        link: function (scope, element, attrs, ctrl) { 
 

 
        }, 
 
        template: "<div>{{::var}} - no extra watchers</div>" 
 
       } 
 
      }) 
 
      .directive("ngBindTwoWayOneTime", function() { 
 
       return { 
 
        scope: { 
 
         var: "=" 
 
        }, 
 
        link: function (scope, element, attrs, ctrl) { 
 

 
        }, 
 
        template: "<div>{{::var}} - no extra watchers</div>" 
 
       } 
 
      }) 
 
      .directive("ngBindTwoWay", function() { 
 
       return { 
 
        scope: { 
 
         var: "=" 
 
        }, 
 
        link: function (scope, element, attrs, ctrl) { 
 

 
        }, 
 
        template: "<div>{{var}} - two extra watchers - declaration and directive</div>" 
 
       } 
 
      }) 
 
      .directive("myDirNoBind", function() { 
 
       return { 
 
        scope: {}, 
 
        link: function (scope, element, attrs) { 
 

 
        }, 
 
        template: "<div>No bindings - no extra watchers</div>" 
 
       } 
 
      }) 
 
    ; 
 
    /** 
 
    * Funkcja do zliczania watchers - max 2000 
 
    */ 
 
    (function() { 
 
     window.countWatchers = function() { 
 
      var root = angular.element(document.getElementsByTagName('body')); 
 

 
      var watchers = []; 
 

 
      var f = function (element) { 
 
       angular.forEach(['$scope', '$isolateScope'], function (scopeProperty) { 
 
        if (element.data() && element.data().hasOwnProperty(scopeProperty)) { 
 
         angular.forEach(element.data()[scopeProperty].$$watchers, function (watcher) { 
 
          watchers.push(watcher); 
 
         }); 
 
        } 
 
       }); 
 

 
       angular.forEach(element.children(), function (childElement) { 
 
        f(angular.element(childElement)); 
 
       }); 
 
      }; 
 

 
      f(root); 
 

 
      // Remove duplicate watchers 
 
      var watchersWithoutDuplicates = []; 
 
      angular.forEach(watchers, function (item) { 
 
       if (watchersWithoutDuplicates.indexOf(item) < 0) { 
 
        watchersWithoutDuplicates.push(item); 
 
       } 
 
      }); 
 
      return watchersWithoutDuplicates.length; 
 
     }; 
 
    })();
<!DOCTYPE html> 
 
<html> 
 

 
    <head> 
 
    <script data-require="[email protected]" data-semver="1.3.6" src="https://code.angularjs.org/1.3.6/angular.js"></script> 
 
    <link rel="stylesheet" href="style.css" /> 
 
    <script src="script.js"></script> 
 
    </head> 
 

 
    <body data-ng-app="myApp"> 
 
<div ng-controller="initCtrl" class="container"> 
 
    <div class="well">Watchers: {{watchers}} - first watcher</div> 
 
    <my-dir ng-model="::dane.zm1"></my-dir> 
 
    <my-dir-ng-model ng-model="dane.zm1"></my-dir-ng-model> 
 
    <my-dir-no-bind></my-dir-no-bind> 
 
    <ng-bind-one-way var="{{::dane.zm1}}"></ng-bind-one-way> 
 
    <ng-bind-two-way var="dane.zm1"></ng-bind-two-way> 
 
    <ng-bind-two-way-one-time var="::dane.zm1"></ng-bind-two-way-one-time> 
 
    <div><a ng-click="change()" href="javascript:void(null)">Change zm1</a></div> 
 
</div> 
 
    </body> 
 

 
</html>

相關問題