javascript - AngularJS : Difference between the $observe and $watch methods

标签 javascript angularjs

我知道 WatchersObservers 都会在 $scope 中的某些内容在 AngularJS 中发生变化时立即计算。但无法理解两者之间究竟有什么区别。

我最初的理解是 Observers 是针对 Angular 表达式计算的,这些表达式是 HTML 端的条件,在 $scope.$watch() 时执行 Watchers 函数被执行。我的想法正确吗?

最佳答案

$observe() Attributes 上的一个方法对象,因此,它只能用于观察/观察 DOM 属性的值变化。它仅在指令内部使用/调用。当您需要观察/观察包含插值的 DOM 属性(即 {{}} 的)时,请使用 $observe。
例如,attr1="Name: {{name}}",然后在指令中:attrs.$observe('attr1', ...) .
(如果你尝试 scope.$watch(attrs.attr1, ...) 它不会因为 {{}} 工作 - 你会得到 undefined.) 使用 $watch 来处理其他所有事情。

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

  • Controller ——任何 Controller ——通过 ng-view、ng-controller 或指令 Controller 创建的 Controller
  • 指令中的链接函数,因为它也可以访问范围

因为字符串被评估为 Angular 表达式,所以当您想要观察/观察模型/范围属性时,经常使用 $watch。例如,attr1="myModel.some_prop",然后在 Controller 或链接函数中:scope.$watch('myModel.some_prop', ...)scope.$watch(attrs.attr1, ...)(或 scope.$watch(attrs['attr1'], ...))。
(如果你尝试 attrs.$observe('attr1') 你会得到字符串 myModel.some_prop,这可能不是你想要的。)

正如@PrimosK 回答的评论中所讨论的,所有 $observes 和 $watches 每隔 digest cycle 进行一次检查。 .

具有隔离作用域的指令更复杂。如果使用 '@' 语法,您可以 $observe 或 $watch 包含插值(即 {{}} 的)的 DOM 属性。 (它与 $watch 一起工作的原因是因为 '@' 语法为我们执行 interpolation,因此 $watch 看到一个没有 {{}} 的字符串。)为了更容易记住何时使用哪个,我建议在这种情况下也使用 $observe。

为了帮助测试所有这些,我写了一个 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。例如,如果你的属性包含一个数字或 bool 值(不是字符串),只需计算一次:attr1="22",然后在你的链接函数中:var count = scope.$eval(attrs.attr1)。如果它只是一个常量字符串——attr1="my string"——那么只需在你的指令中使用attrs.attr1(不需要$eval())。

另见 Vojta's google group post关于 $watch 表达式。

关于javascript - AngularJS : Difference between the $observe and $watch methods,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14876112/

相关文章:

javascript - react HOC : render hijacking with functional components

javascript - MongoDB 和 URL 路由

javascript - 舍入javascript变量

java - AngularJS JSON Spring MVC 应用程序中的文件上传 400 错误请求所需的请求部分不存在

javascript - 缩小 angularjs 应用程序时出现错误 : Unexpected token punc «)», 预期的 punc «,»

jquery - 用于从菜单中删除文本的 CSS3 转换?

我的 ASCX 控件上的 Javascript 没有将我重定向到新页面/控件

javascript - 使用 AngularJS 创建自定义属性

c# - 是否可以将数据从 AngularJS 传递到 Web 服务中带有模型参数的函数?

javascript - 如何用 mustache 配置数组迭代?