AngularJs $parse、$eval和$observe、$watch详解
$parse和$eval
$parse和$eval这两个函数都可以解析表达式的值.
它们的区别在于$parse是一个服务,可以注入使用.$eval是scope对象上的一个方法,我们只能在能访问scope的场景下使用它.
vargetter=$parse('user.name'); varsetter=getter.assign; varcontext={user:{name:'JohnDoe'}; varlocals={user:{name:'DoeJohn'}; getter(context);//JohnDoe setter(context,'newname'); getter(context);//newname getter(context,locals);//DoeJohn
$parse服务接收一个表达式作为参数并返回一个函数.这个函数可以被调用,其中的参数是一个context对象,通常来说是作用域.
另外,这个函数有一个assign属性.它也是一个函数,可以用来在给定的上下文中改变这个表达式的值.最后一行代码演示了如何使用locals来覆盖context对象.
$eval用起来要简单很多,因为它的上下文已经被指定为scope对象.
varscope=$rootscope.$new(true); scope.a=1; scope.b=2; scope.$eval('a+b')//3 scope.$eval(function(scope){ returnscope.a+scope.b; });//3
关于$parse和$eval之间的关系,我们能从Angular源码中看出来,可以说$eval是为了让$parse在scope中使用更方便的语法糖.
$eval:function(expr,locals){ return$parse(expr)(this,locals); }
$eval还有个同胞兄弟,$evalAsync,它并不会立刻计算表达式的值,而是将表达式缓存起来,等到下一次$digest(脏检查)的时候执行.以获取更好的性能.
$observe和$watch
$observe和$watch都可以监听表达式值的变化.但有显著的不同.
$observe是angular指令中link函数第三个参数(attrs)的一个方法.只能在指令的link函数中使用它.它是通过$evalAsync函数实现监控的.
$watch是scope对象上的一个方法,watch表达式很灵活,可以是一个函数,可以是scope上的属性,也可以是一个字符串形式的表达式.监听scope上的属性名或表达式的时候,会利用$parse服务将表达式转换成一个函数,这个函数会在$digest中被调用.$watch的第三个参数"objectEquality",指定比较对象的方式,如果为true,则用angular.equals,否则直接比较引用.默认为false.
//html <divbook="{{book.name}}"></div> //js attrs.$observe('book',function(newValue){ //justhaveoneparameter,can'tgetoldvalue }); scope.$watch(attrs.book,function(newValue,oldValue){ //getundefined });
当你需要监听一个包含"{{}}"的DOM属性时,使用$observe,如果用$watch,只能得到undefined.反之,就用$watch.如果用$observe,只能得到一个固定的字符串.
//html <divbook="book.name"></div> //js attrs.$observe('book',function(newValue){ //alwaysget'book.name' }); scope.$watch(attrs.book,function(newValue,oldValue){ });
有一个特殊的情况,当你的指令使用了独立的作用域(scope:{}),那些应用了"@"语法的DOM属性,即使包含"{{}}",也可以被$watch.
因为@前缀标识符,它的实现是通过$observe去监听DOM属性的变化,这就是为什么@attr的值只能是字符串或是"{{}}",而不能是scope上的属性,所以最终$watch看到的表达式是没有"{{}}"的.而"="和"&"则是基于$watch实现.所以=attr,&attr的值不能包含"{{}}",但可以直接使用scope上的属性.
$watchGroup和$watchCollection
$watchGroup是用来监听一组表达式.数组中任意表达式的变化都会触发监听函数.
$scope.teamScore=0; $scope.time=0; $scope.$watchGroup(['teamScore','time'],function(newVal,oldVal){ //newValandoldValarebotharray });
$watchCollection用来监听一个对象(包括数组),当这个对象的任意属性发生变化时,触发监听函数.和$watch一样,第一次参数可以是一个返回一个对象的函数.
$scope.names=['igor','matias','misko','james']; $scope.dataCount=4; $scope.$watchCollection('names',function(newVal,oldVal){ $scope.dataCount=newVal.length; }); $timeout(function(){ $scope.names.pop(); },2000);
$observe,$watch,$watchGroup,$watchCollection都返回一个移除监听的函数.当需要取消监听的时候,直接调用.
varoff=scope.$watch('name',function(newValue,oldValue){ }); off();
以上就是对AngularJs$parse、$eval和$observe、$watch的知识详解,谢谢大家对本站的支持!