AngularJS:$ observe和$ watch方法之间的区别

2020/09/29 16:21 · javascript ·  · 0评论

我知道,无论WatchersObservers就将计算在东西$scope在AngularJS变化。但是无法理解两者之间到底有什么区别。

我最初的理解是Observers为角表达式计算的,这些角表达式是在Watchers执行$scope.$watch()功能在HTML端执行的条件。我在想适当吗?

$ observe() Attributes对象上的一种方法,因此,它只能用于观察/监视DOM属性的值更改。仅用于/调用内部指令。需要观察/观察包含插值的DOM属性(即{{}})时,请使用$ observe。

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

(如果您尝试scope.$watch(attrs.attr1, ...)使用{{}},则无法undefined使用-您会得到的。)将$ watch用于其他所有内容。

$ watch()更复杂。它可以观察/观察“表达式”,其中表达式可以是函数或字符串。如果表达式是字符串,则将 $ parse'd(即,作为 Angular表达式求值)放入函数中。(每个摘要循环都会调用此函数。)字符串表达式不能包含{{}}。$ watch是 Scope对象上的一个方法,因此可以在任何有权访问范围对象的地方使用/调用它,因此在

  • 一个控制器-任何控制器-一个通过ng-view,ng-controller或指令控制器创建的控制器
  • 指令中的链接函数,因为它也可以访问作用域

因为字符串是作为Angular表达式求值的,所以当您要观察/观察模型/作用域属性时,通常使用$ watch。例如,attr1="myModel.some_prop"然后在控制器或链接功能中:scope.$watch('myModel.some_prop', ...)scope.$watch(attrs.attr1, ...)(或scope.$watch(attrs['attr1'], ...))。

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

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

具有单独作用域的指令更加复杂。如果使用'@'语法,则可以$ observ 或$ watch包含插值(即{{}})的DOM属性。(它与$ watch一起使用的原因是因为'@'语法为我们进行插值,因此$ watch看到的字符串中没有{{}}。)为了更容易记住何时使用哪个字符串,我建议使用$也观察这种情况。

为了帮助测试所有这些,我编写了一个Plunker,它定义了两个指令。一个(d1)不创建新的作用域,另一个(d2)创建隔离的作用域。每个指令具有相同的六个属性。每个属性都是$ observe'd和$ watch'ed。

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

查看控制台日志以查看链接功能中$ observe和$ watch之间的区别。然后单击链接,查看单击处理程序进行的属性更改触发了哪些$ observes和$ watches。

请注意,当链接函数运行时,尚未评估任何包含{{}}的属性(因此,如果您尝试检查这些属性,则会得到undefined)。查看插值的唯一方法是使用$ observe(如果使用带'@'的隔离范围,则使用$ watch)。因此,获取这些属性的值是异步操作。(这就是为什么我们需要$ observe和$ watch函数。)

有时您不需要$ observe或$ watch。例如,如果您的属性包含数字或布尔值(不是字符串),则只需对其进行一次评估:attr1="22",然后在您的链接函数:中进行评估var count = scope.$eval(attrs.attr1)如果它只是一个常量字符串– attr1="my string"–则只需attrs.attr1在您的指令中使用(不需要$ eval())。

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

如果我正确理解您的问题,您在问如果用注册监听器回调$watch用注册回调有什么区别$observe

执行$watch$digest触发向其注册的回调

$observe当包含插值的属性的值更改时(例如attr="{{notJetInterpolated}}"将调用注册到的回调


内部指令可以两种非常相似的方式使用它们:

    attrs.$observe('attrYouWatch', function() {
         // body
    });

要么

    scope.$watch(attrs['attrYouWatch'], function() {
         // body
    });

我认为这很明显:

  • $ observe用于指令的链接功能。
  • $ watch用于观察值的任何变化。

请记住:这两个函数都有两个参数,

$observe/$watch(value : string, callback : function);
  • value:始终是对监视元素的字符串引用(范围变量的名称或要监视的指令属性的名称)
  • callback:要执行的函数的形式function (oldValue, newValue)

我做了一个plunker,所以您实际上可以了解它们的利用率。我使用了变色龙类比,以使其更容易描绘。

为什么$ observe与$ watch不同?

将对watchExpression进行评估,并将其与每个digest()周期中的先前值进行比较,如果watchExpression值发生变化,则会调用watch函数。

$ observe专门用于监视插值。如果插入指令的属性值,例如dir-attr="{{ scopeVar }}",则仅在设置了插入值时(因此,在$ digest已经确定需要进行更新时),将调用observe函数。基本上,已经有了插值的监视程序,并且$ observe函数支持此操作。

请参阅compile.js中的 $ observe和$ set

本文地址:http://javascript.askforanswer.com/angularjs-observehe-watchfangfazhijiandequbie.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!