我知道,当$scope中的某些东西在AngularJS中发生变化时,WatchersObservers都会被计算出来.但我不明白这两者到底有什么区别.

我最初的理解是,Observers是为Angular 表达式计算的,这是HTML端的条件,当执行$scope.$watch()函数时执行as Watchers.我想得对吗?

推荐答案

$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. It is only used/called inside directives. Use $observe when you need to observe/watch a DOM attribute that contains interpolation (i.e., {{}}'s).
E.g., attr1="Name: {{name}}", then in a directive: 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.

$watch() is more complicated. 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 (i.e., evaluated as an Angular expression) into a function. (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

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

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

正如@PrimosK的答案 comments 中所讨论的,所有$observes和$watches每digest cycle次判断一次.

Directives with isolate scopes are more complicated. If the '@' syntax is used, you can $observe or $watch a DOM attribute that contains interpolation (i.e., {{}}'s). (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.

为了帮助测试所有这些,我编写了一个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>

查看控制台日志(log),查看链接功能中$observe和$watch之间的差异.然后单击链接,查看单击处理程序所做的属性更改触发了哪些$observes和$watches.

请注意,当link函数运行时,包含{{}的所有属性都尚未计算(因此,如果您try 判断这些属性,将得到undefined).查看插值的唯一方法是使用$observe(如果使用带"@"的隔离作用域,则使用$watch).因此,获取这些属性的值是一个简单的操作.(这就是为什么我们需要$observe和$watch功能.)

Sometimes you don't need $observe or $watch. E.g., 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). If it is just a constant string – attr1="my string" – then just use attrs.attr1 in your directive (no need for $eval()).

另见Vojta's google group post美元左右的手表表情.

Javascript相关问答推荐

通过JavaScript将CSS与音频大声噪音同步

Flutter:显示PDF和视频,但阻止下载

鼠标移动时更新画布

如果没有尾随斜线,托管在收件箱中的React/Vite将无法工作

如何使用Paged.js仅渲染特定页面

当promise 在拒绝处理程序被锁定之前被拒绝时,为什么我们会得到未捕获的错误?

微软Edge Select 间隙鼠标退出问题

窗口.getComputedStyle()在MutationObserver中不起作用

在vercel throws上部署带有gunjs的sveltekit应用无法找到模块./' lib/文本编码'

JS,当你点击卡片下方的绿色空间,而它是在它的背后转动时,

实现JS代码更改CSS元素

虚拟滚动实现使向下滚动可滚动到末尾

我怎么才能得到Kotlin的密文?

这个值总是返回未定义的-Reaction

在Matter.js中添加从点A到另一个约束的约束

在VS代码上一次设置多个变量格式

一个实体一刀VS每个实体多刀S

我想使用GAS和HTML将从Electron 表格中获得的信息插入到文本字段的初始值中

如何使用画布在另一个内部绘制一个较小但相同的形状,同时保持恒定的边界厚度?

AG-GRIDreact 显示布尔值而不是复选框