angular的$watch和$observe的区别,翻译自Stack Overflow

https://stackoverflow.com/questions/14876112/angularjs-difference-between-the-observe-and-watch-methods

首先贴原文地址。用我笨拙的英语翻译下,方便不懂英语的理解,如有更好的翻译可以轻拍砖。。。

$observe是Attrbutes对象的一个方法,因此,它只能被用于观察DOM的attribute属性的值的改变,只能被指令内部使用或调用。当你需要观察一个DOM的attribute包含插入值(例如 attr1="Name: {{name}}",然后在指令内部 attrs.$observe(attrs, ...) 假如你试着在指令内部 scope.$watch(attrs.attr1, ...) 这样是不会起作用的,只会得到undefined。

$watch就比较复杂了,它可以观察表达式,也就是可以是一个function或者string字符串。假如表达式是一个字符串,它将被解析为一个function(这个function会在每次digest循环都被执行)。字符串不能包含{{}}。$watch是scope上面的一个方法,因此可以用在


一个controller,通过ng-view,ng-controller或一个directive的controller

在directive的link function,因为这个也可以连接到scope


因为字符串被当做angular的表达式,$watch通常被用于你想观察一个model或者scope的属性(例如 attr1="myModel.some_prop",然后controller或者link function: scope.$watch('myModel.some_prop', ...) 或者 scope.$watch(attrs.attr1, ...) )

假如你试着 attrs.$observe('attr1'), 你将会得到字符串 myModel.some_prop,这应该不是你想要的。

所有的$observe和$watch在每次digest循环都会被检测。

独立作用域的指令更复杂。假如使用了@符号,你可以$observe或者$watch一个DOM被插入的attribute($watch也可以工作的原因是由于@符号帮助我们做了插入(interpolation),因此$watch可以看到没有{{}}的字符串。(这里翻译的不知道对不对,请指正))。为了更容易记住何时使用,我建议在这种情况下也使用$observe。

为了帮助我们验证所有这些,作者写了一个plunker(http://plnkr.co/edit/HBha8sVdeCqhJtQghGxw?p=preview)。定义了两个指令,d1指令没有创造一个新的scope,d2新创造了一个独立的scope。每个指令都有相同的6个attributes属性。每个属性都被$watch和$observe。

<div d1 attr1="{{prop1}}-test" attr2="prop2" attr3="33" attr4="'a_string'"
        attr5="a_string" attr6="{{1+aNumber}}"></div>

打开控制台的console标签页查看$observe和$watch在link function中不同的表现。然后点击链接查看属性改变后被click方法触发后的$observe和$watch。

注意当link function运行时,所有包含的{{}}还没有被执行。查看插入值的唯一方法是使用$observe(或者$watch,假如你使用的是独立的scope和@)。因此,获得这些属性值是一个异步的操作。

有时你不需要$observe或者$watch。比方说你的attribute包含一个number或者Boolean(不能是字符串)直接直接执行一次:attr1="22",相当于在你的link function里面 var count = scope.$eval(attrs.attr1)。假如只是一个常量字符串(例如attr1="my string", 那就直接在你的指令里使用attrs.attr1,不需要$eval())。