第一部分:$watch
$watch是一个scope函数,用于监听模型变化,当你的模型部分发生变化时它会通知你。
$watch(watchExpression, listener, objectEquality);
每个参数的说明如下:
watchExpression:监听的对象,它可以是一个angular表达式如‘name‘,或函数如function(){return $scope.name}。
listener:当watchExpression变化时会被调用的函数或者表达式,它接收3个参数:newValue(新值), oldValue(旧值), scope(作用域的引用)
objectEquality:是否深度监听,如果设置为true,它告诉Angular检查所监控的对象中每一个属性的变化. 如果你希望监控数组的个别元素或者对象的属性而不是一个普通的值, 那么你应该使用它
可参考:
http://yuankeqiang.lofter.com/post/8de51_1454f93
http://www.angularjs.cn/A0a6
官网:http://docs.angularjs.cn/api/ng/type/$rootScope.Scope
第二部分:$watch,$digest和$apply
最近项目上使用了比较多的angular JS,一直都对它感觉比较陌生,总觉得有点反直觉,这段时间,准备下定决心弄明白,这个框架到底是怎么一回事,以及它的工作原理,生命周期……一点一点的啃完它吧。首先,让我们先来看看watch、digest、$apply这三个方法吧!
Param | Type | Details |
watchExpression |
function() string |
Expression that is evaluated on each $digest cycle. A change in the return value triggers a call to the listener.
|
listener (optional) |
function() string |
Callback called whenever the return value of the watchExpressionchanges.
|
objectEquality (optional) |
boolean | Compare object for equality rather than for reference. |
从表格中可以看到,watchExpression和listener可以是一个string,也可以是一个function(scope)。该表达式在每次调用了$digest方法之后都会重新算值,如果返回值发生了改变,listener就会执行。在判断newValue和oldValue是否相等时,会递归的调用angular.equals方法。在保存值以备后用的时候调用的是angular.copy方法。listener在执行的时候,可能会修改数据从而触发其他的listener或者自己直到没有检测到改变为止。Rerun Iteration的上限是10次,这样能够保证不会出现死循环的情况。
$watch的基本结构如下:
//$scope.$watch(<function/expression>, <handler>); $scope.$watch(‘foo‘, function(newVal, oldVal) { console.log(newVal, oldVal); }); //or $scope.$watch(function() { return $scope.foo; }, function(newVal, oldVal) { console.log(newVal, oldVal); });
该方法会触发当前scope以及child scope中的所有watchers,因为watcher的listener可能会改变model,所以$digest方法会一直触发watchers直到不再有listener被触发。当然这也有可能会导致死循环,不过angular也帮我们设置了上限10!否则会抛出“Maximum iteration limit exceeded.”。
通常,我们不在controller或者directive中直接调用digest方法,而是调apply方法,让apply方法去调用digest方法。
如何调用该方法呢?
$scope.$digest();
Param | Type | Details |
exp (optional) |
string function() |
An angular expression to be executed.
|
个人理解,apply方法就是将digest方法包装了一层,exp是可选参数,可以是一个string,也可以是function(scope)。伪代码(来自官方文档)如下:
function $apply(expr) { try { return$eval(expr); } catch(e) { $exceptionHandler(e); } finally { $root.$digest(); } }
$apply方法使得我们可以在angular里面执行angular框架之外的表达式,比如说:浏览器DOM事件、setTimeout、XHR或其他第三方的库。由于我们要在angular框架内调用,我们必须得准备相应的scope。调用方式如下:
$scope.$apply(‘foo = "test"‘); //or $scope.$apply(function(scope) { scope.foo = ‘test‘; }); //or $scope.$apply(function(){ $scope.foo = ‘test‘; });
至于angular js为什么要这么做,请看我上一篇博客angular js之scope.$apply方法。
===============================================================================
该方法支持value types,regular expressions、arrays、objects。官方文档写的很清楚:
Two objects or values are considered equivalent if at least one of the following is true:
During a property comparison, properties of function type and properties with names that begin with $ are ignored.
Scope and DOM Window objects are being compared only by identify (===).
来源:http://www.cnblogs.com/penghongwei/p/3400535.html
原文:http://www.cnblogs.com/simonbaker/p/5225963.html