$observe $watch都可以用来监听值的变化,但是他们有显著的区别。$observe是用来监视DOM属性值的变化,而 $watch监视scope属性值的变化。AngularJS中的监听,都知道的有$watch,还有一种监听是$observe,$watch主要监听的是$scope上的属性,而$observe监听的是directive中attrs上的属性。
attrs.$observe('attr1', ....)
scope.$watch(“model.property”...)
一、要点
1、$watch
$watch()
是angular
上scope
对象的一个方法。- 任何一个控制器中,但是不推荐在在
控制器
中使用$watch()
;因为这样使得测试
和维护
变得很困难。 - 任何一个指令中,可以在指令的
link
函数中使用,这是一种推荐的方式。 - 他不但可以监测
angular expression
的变化,还可以检测function(){}
函数的变化,监测angular expression
的时候会使用$parse
将angular expression
解析为一个函数,这个函数会在angular
的每个脏值检查
循环中被调用。
2、$observe
$observe()
是angular
指令中link
函数中实例属性
即(iAttr
)的一个方法。- 只可以在指令中使用,也是在指令的
link
函数中使用。 - 它只能够监测
angular expression
的变化,监测的方式和上面$watch()
监测angular expression
的方式一样。
二、区别
$observe是属性对象上的方法,因此它是用来监控DOM属性上的值的变化,它仅用在指令内部,当你需要在指令内部监控包含有插值表达式({{}})的DOM属性的时候,就要用到这个方法,比如,
attr1="Name:{{name}}"
,
然后在指令里面:attrs.$observe('attr1', ....)
,
但是假如你只用scope.$watch(attrs.attr1,...)
,这种情况下是无效的,因为{{}}
无法被解析,所以你得到的是undefined
, 在其他情况下用$watch。
1、指令(不使用隔离的作用域)
在不使用隔离的作用域的指令
中,$watch()
只能够监测不带有插值标记({{}})的angular expression
,比如在<div attr1='expr' attr2='{{expr}}'></div>
中,只可以监测attr1='expr'
中的attr1
,监测attr2
只能够得到一个undefined
,因为存在{{}}
插值符号。
在不使用隔离的作用域的指令
中,$observe()
只能够监测带有插值标记的angular expression
,比如在<div attr1='expr' attr2='{{expr}}'></div>
中,只可以监测attr2='{{expr}}'
中的attr2
,监测attr1
只会得到一个一成不变的字符串expr
。
2、指令(使用隔离的作用域)
在使用隔离的作用域的指令中
,$watch()
也可以监测带有插值标记({{}})的angular expression
;因为使用了@
或者=
前缀标识符,它们已经帮我们实现了插值
,所以可以这样使用。
三、例子
1、$watch
currentChargeType为$scope上的内容
var initWatch = function () { var closeWatchMethod = $scope.$watch('currentChargeType', function (newValue, oldValue) { if (!newValue) return; $scope.currentChargeApplyType = chargeBaseToolUtil.upperWordFirst(newValue) + 'Charge'; initComboBox(); closeWatchMethod(); }); };
2、$observe
attrs.$observe('popShow', function (val) { $timeout(function () { var event = (val && (val == 'true' || val == true)) ? 'show' : 'hide'; element.popover(event); }); });