角度2的变化检测是否总是从根部开始

Does change detection in angular2 always start in root component?

本文关键字:根部 开始 是否 变化检测 角度      更新时间:2024-03-11

考虑Angular2 中的以下组件树结构

     A
  B     C
D  E   F  G

如果G通过点击C发出事件,而C没有进一步发送该事件

html

<div (click)="update($event)"></div>

component

@Output() myOutputName = new EventEmitter();
update(event) {
    this.myOutputName.emit('some vlaue'); 
}

变更检测是从A开始在所有节点中运行,还是从C开始并仅影响FG

是,更改检测始终从根组件开始

幻灯片-http://pascalprecht.github.io/slides/angular-2-change-detection-explained/#/54

数据总是从上到下流动,这是因为变化检测也是始终对每个组件从上到下执行单次,从根组件开始

因此,如果G发出事件,

更改检测将从根组件开始

 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbspA nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp (change detection in A)

 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbspB nbsp nbsp C nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp;(change detection in B,C)

 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp D nbsp E nbsp nbsp F nbsp G nbsp nbsp nbsp nbsp nbsp;(change detection in D,E,F,G)

请记住,有一些方法可以处理变化检测

但默认为是,更改检测从根开始

为了进一步参考,

文章
1)http://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html
2)http://victorsavkin.com/post/110170125256/change-detection-in-angular-2

变更检测是否运行

这取决于情况。默认情况下,更改检测将在每个异步事件(好吧,Zone.js对每个异步事件进行了monkey修补)之后运行,从组件树的顶部/根开始,然后按深度优先顺序访问每个节点一次。所以A-B-D-E-C-F-G(不是A-B-C-D-E-F-G,它将是广度第一阶)。

但是,如果对组件G禁用了更改检测(请参阅detach()),则在单击处理程序运行后将不会运行更改检测。

更改检测是否在所有节点中运行

同样,这取决于情况。默认情况下为"是",将选中每个节点。

然而,组件可以从变化检测器树中分离(正如我刚才提到的),也可以配置为使用OnPush变化检测策略。如果组件使用OnPush,则只有在以下条件/事件之一"标记"进行检查时,才会对其进行检查:

  • 它的一个输入属性已更改
  • 组件触发了一个事件(即,其模板中的某个事件绑定触发了事件)
  • 可观察到的激发了一个事件,该可观察到与视图/模板中的| async一起使用
  • 通过调用markForCheck()–这可以在组件逻辑中调用,也可以在某些子逻辑中调用(下面将详细介绍)

如果OnPush组件未"标记",则不会检查该组件是否发生了更改,也不会检查其任何后代(无论它们使用的更改检测策略如何)。因此,如果组件G使用默认的更改检测策略,但父组件C使用OnPush,如果C没有标记为检查,则G也不会被检查。

可以使用markForCheck()手动标记OnPush组件。此方法还将标记其所有祖先直至根组件。它必须这样做,因为更改检测总是从根开始。。。为了进行更改检测,使其返回到"标记的"组件,Angular必须确保链/树上的任何其他OnPush组件也被标记。否则,更改检测将永远不会返回到此组件。

对于只使用输入属性(即,它们不从服务中获取数据)的叶节点/组件,OnPush通常是一个不错的选择


默认情况下,更改检测始终从根组件开始。但是,如果手动调用detectChanges(),它将只检查当前零部件及其子体。