angularjs - Does Angular create a new watcher if one already exists? -


consider:

angular   .module('app', [])   .controller('maincontroller', function($scope) {     $scope.$watch('bool', function(newval, oldval) {     });     console.log($scope);   }); 

and

<body ng-controller='maincontroller'>   <p ng-class="{'blue': bool, 'red': !bool}">ngclass</p>   <p ng-show='bool'>ngshow</p>   <input type='checkbox' ng-model='bool' /> </body> 

plnkr of above

it seems there 3 watchers being created:

  1. from $scope.$watch.
  2. from ngshow.
  3. from ngclass.

(note: directives involved in data binding use $scope.$watch internally.)

enter image description here

i have thought since they're watching bool property, there'd 1 watcher , it'd have multiple listener callbacks.


edit: case it's saying, "has bool changed? if run cb1. has bool changed? if run cb2. has bool changed? if run cb3." or case it's saying, "has bool changed? if run cb1, cb2, , cb3." if former, why on latter?

questions:

  1. is interpretation correct? there multiple watches being registered?
  2. what implications performance?
  3. bonus: if interpretation correct , multiple watchers being added, why designed this? why changes bool 3 times instead of 1?

example 2) - want make sure 2 passwords in form match, , if don't, show error. assume have:

ng-class="{invalid: myform.myinput1.$touched && ctrl.myinput1  != ctrl.myinput2}"  

say want use $setvalidity update validity of form. might idea do:

ng-class="{invalid: myform.myinput1.$touched && ctrl.functiontocheckinputs(myform)}" 

and call $setvalidity inside of functiontocheckinputs rather using $scope.$watch , doing $setvalidity inside of it? because latter adds additional watcher (presumably).

there multiple $watchers being registered. in fact, if had 2 exact expressions:

$scope.$watch("foo", cb1) $scope.$watch("foo", cb2) 

you'd still 2 $watchers.

to answer question - former case, i.e. "if "foo" expression changed, run cb1, if "foo" expression changed, run cb2, etc... why? because, $watcher potentially change return value of $scope.foo; not in callback, in expression itself. angular needs re-evaluate expressions every time account possibility.

the length of digest cycle plays significant factor on performance.

first, number of $watchers, cause watched expression or function evaluate. so, reducing number of $watchers, preferring one-way two-way watch, or use one-time watch suitable, improves performance.

second, complexity of watched functions. these functions should fast - ideally, not more getters. example, avoid following:

<div ng-class="{active: isactive(id)}"> 
$scope.isactive = function(id){    (var i=0; i<items.length; i++){       if (items[i].id == id && items[0].active) return true;    }    return false; }; 

Comments

Popular posts from this blog

Fail to load namespace Spring Security http://www.springframework.org/security/tags -

sql - MySQL query optimization using coalesce -

unity3d - Unity local avoidance in user created world -