在作用域与父作用域中观察相同值的变化——有区别吗?

Watching in scope vs parent scope for the same value change - is there a difference?

我有一个关于 Angular 手表的非常基本的问题。假设我在指令的 link 函数中有以下内容:

scope.$watch(function(){
    return element.isVisible();
  }, myFuncUponVisibleChange);

这是否与以下内容相同:

scope.$parent.$watch(function(){
     return element.isVisible();
  }, myFuncUponVisibleChange);

换句话说,Angular 是否在上述两种情况下观察同一元素的可见性?

是的。 $element 是什么不会改变,因为当您声明该函数时,您正在捕获该范围内的 $element 引用(JavaScript 范围,而不是 Angular 范围)。

现在如果你做了这样的事情:

scope.$parent.$watch('$element.isVisible()', myFuncUponVisibleChange);

那就完全不同了,因为那时你会从父范围引用 $element,而不是其他范围。

是的,两个作用域观察者都观察同一个元素,因为 element 指的是特定对象,并且它在观察者函数中被引用。

是的,有很大的不同。

AngularJS 中的很多性能问题都是由于摘要循环影响整个范围层次结构这一事实造成的。也就是说,$scope.$apply()会触发从上到下的所有观察者。

一旦应用程序足够复杂(它始终取决于客户端和应用程序,但为简单起见,关键点通常估计为约 1000 个观察者),它开始对摘要无响应。

优化它的一个好方法是封装指令更改并防止指令在根范围内宣布摘要,除非全局摘要是所需的行为。在这种情况下,可以调用 $scope.$digest() 而不是 $scope.$apply()(两者之间的根本区别在于后者 calls $rootScope.$digest())。

不一样的地方来了。 scope.$parent.$watch(...) 观察者不会在 $scope.$digest() 上触发,但会在 $scope.$apply() 上触发。它说明了为什么指令隔离很重要,以及为什么从子级引用父级作用域是个坏习惯。

另一个令人不快的惊喜是scope.$parent.$watch(...)可能会导致内存泄漏。如果拥有 scope 的元素被销毁,watcher 不会被自动清理。它将引用分离 element,防止对象被垃圾收集。

$scope.$parent是邪恶的