Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
361 views
in Technique[技术] by (71.8m points)

javascript - AngularJS:$ observe和$ watch方法之间的区别(AngularJS : Difference between the $observe and $watch methods)

I know that both Watchers and Observers are computed as soon as something in $scope changes in AngularJS.

(我知道AngularJS中$scope中的某些更改会立即计算WatchersObservers 。)

But couldn't understand what exactly is the difference between the two.

(但是无法理解两者之间到底有什么区别。)

My initial understanding is that Observers are computed for angular expressions which are conditions on the HTML side where as Watchers executed when $scope.$watch() function is executed.

(我最初的理解是, Observers是针对角度表达式计算的,这些角度表达式是HTML端的条件,在Watchers执行$scope.$watch()函数时执行。)

Am I thinking properly?

(我的想法是否正确?)

  ask by Abilash translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

$observe() is a method on the Attributes object, and as such, it can only be used to observe/watch the value change of a DOM attribute.

($ observe()Attributes对象上的一种方法,因此,它只能用于观察/监视DOM属性的值更改。)

It is only used/called inside directives.

(仅用于/调用内部指令。)

Use $observe when you need to observe/watch a DOM attribute that contains interpolation (ie, {{}}'s).

(当需要观察/观察包含插值的DOM属性(即{{}})时,请使用$ observe。)


Eg, attr1="Name: {{name}}" , then in a directive: attrs.$observe('attr1', ...) .

(例如, attr1="Name: {{name}}" ,然后在指令中: attrs.$observe('attr1', ...) 。)


(If you try scope.$watch(attrs.attr1, ...) it won't work because of the {{}}s -- you'll get undefined .) Use $watch for everything else.

((如果尝试使用scope.$watch(attrs.attr1, ...) ,则由于{{}}而无法正常工作-您将无法undefined 。)将$ watch用于其他所有内容。)

$watch() is more complicated.

($ watch()更复杂。)

It can observe/watch an "expression", where the expression can be either a function or a string.

(它可以观察/观察“表达式”,其中表达式可以是函数或字符串。)

If the expression is a string, it is $parse 'd (ie, evaluated as an Angular expression ) into a function.

(如果表达式是字符串,则将$ parse'd (即,作为Angular表达式求值)放入函数中。)

(It is this function that is called every digest cycle.) The string expression can not contain {{}}'s.

((每个摘要周期都会调用此函数。)字符串表达式不能包含{{}}。)

$watch is a method on the Scope object, so it can be used/called wherever you have access to a scope object, hence in

($ watch是Scope对象上的一种方法,因此可以在任何有权访问scope对象的地方使用/调用它,因此在)

  • a controller -- any controller -- one created via ng-view, ng-controller, or a directive controller

    (一个控制器-任何控制器-一个通过ng-view,ng-controller或指令控制器创建的控制器)

  • a linking function in a directive, since this has access to a scope as well

    (指令中的链接函数,因为它也可以访问作用域)

Because strings are evaluated as Angular expressions, $watch is often used when you want to observe/watch a model/scope property.

(因为字符串是作为Angular表达式求值的,所以当您要观察/观察模型/作用域属性时,通常使用$ watch。)

Eg, attr1="myModel.some_prop" , then in a controller or link function: scope.$watch('myModel.some_prop', ...) or scope.$watch(attrs.attr1, ...) (or scope.$watch(attrs['attr1'], ...) ).

(例如, attr1="myModel.some_prop" ,然后在控制器或链接函数中: scope.$watch('myModel.some_prop', ...)scope.$watch(attrs.attr1, ...) (或scope.$watch(attrs['attr1'], ...) )。)


(If you try attrs.$observe('attr1') you'll get the string myModel.some_prop , which is probably not what you want.)

((如果尝试使用attrs.$observe('attr1')myModel.some_prop获得字符串myModel.some_prop ,这可能不是您想要的。))

As discussed in comments on @PrimosK's answer, all $observes and $watches are checked every digest cycle .

(如对@PrimosK答案的评论中所讨论的,每个摘要周期都会检查所有$ observes和$ watches。)

Directives with isolate scopes are more complicated.

(具有单独作用域的指令更加复杂。)

If the '@' syntax is used, you can $observe or $watch a DOM attribute that contains interpolation (ie, {{}}'s).

(如果使用“ @”语法,则可以$ observ 或$ watch包含插值(即{{}})的DOM属性。)

(The reason it works with $watch is because the '@' syntax does the interpolation for us, hence $watch sees a string without {{}}'s.) To make it easier to remember which to use when, I suggest using $observe for this case also.

((它与$ watch一起使用的原因是因为'@'语法为我们进行了插值 ,因此$ watch看到的字符串中没有{{}}。)为了更容易记住何时使用哪个字符串,我建议使用$在这种情况下也要观察。)

To help test all of this, I wrote a Plunker that defines two directives.

(为了帮助测试所有这些,我编写了一个Plunker ,它定义了两个指令。)

One ( d1 ) does not create a new scope, the other ( d2 ) creates an isolate scope.

(一个( d1 )不创建新的作用域,另一个( d2 )创建隔离的作用域。)

Each directive has the same six attributes.

(每个指令具有相同的六个属性。)

Each attribute is both $observe'd and $watch'ed.

(每个属性都是$ observe'd和$ watch'ed。)

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

Look at the console log to see the differences between $observe and $watch in the linking function.

(查看控制台日志,以查看链接功能中$ observe和$ watch之间的区别。)

Then click the link and see which $observes and $watches are triggered by the property changes made by the click handler.

(然后单击链接,查看单击处理程序所做的属性更改触发了哪些$ observes和$ watches。)

Notice that when the link function runs, any attributes that contain {{}}'s are not evaluated yet (so if you try to examine the attributes, you'll get undefined ).

(请注意,当链接函数运行时,尚未评估任何包含{{}}的属性(因此,如果您尝试检查这些属性,则会得到undefined )。)

The only way to see the interpolated values is to use $observe (or $watch if using an isolate scope with '@').

(查看插值的唯一方法是使用$ observe(如果使用带'@'的隔离范围,则使用$ watch)。)

Therefore, getting the values of these attributes is an asynchronous operation.

(因此,获取这些属性的值是异步操作。)

(And this is why we need the $observe and $watch functions.)

((这就是为什么我们需要$ observe和$ watch函数。))

Sometimes you don't need $observe or $watch.

(有时您不需要$ observe或$ watch。)

Eg, if your attribute contains a number or a boolean (not a string), just evaluate it once: attr1="22" , then in, say, your linking function: var count = scope.$eval(attrs.attr1) .

(例如,如果您的属性包含数字或布尔值(不是字符串),则只需对其进行一次评估: attr1="22" ,然后在例如您的链接函数中: var count = scope.$eval(attrs.attr1) 。)

If it is just a constant string – attr1="my string" – then just use attrs.attr1 in your directive (no need for $eval()).

(如果它只是一个常量字符串– attr1="my string" –则只需在指令中使用attrs.attr1 (不需要$ eval())。)

See also Vojta's google group post about $watch expressions.

(另请参见Vojta在Google网上论坛上发布的有关$ watch表达式的信息。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...