繁体   English   中英

Angular2中的更改检测是否总是从根组件开始?

[英]Does change detection in angular2 always start in root component?

考虑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发出事件,

更改检测将从根组件开始,

A (change detection in A) A (change detection in A)

B C (change detection in B,C)

D E F G (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用猴子修补的每个异步事件)之后运行,从组件树的顶部/根目录开始,然后按深度优先顺序访问每个节点一次。 因此,ABDECFG(不是ABCDEFG,这是广度优先的顺序)。

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

变更检测是否在所有节点上运行

再次,这取决于。 默认情况下是,将检查每个节点。

但是,可以将组件与变更检测器树分离(如我刚刚提到的那样),也可以将它们配置为使用OnPush变更检测策略。 如果组件使用OnPush ,则仅通过以下条件/事件之一检查它是否被“标记”为检查:

  • 其输入属性之一已更改
  • 组件触发了一个事件(即,其模板中的某些事件绑定触发了一个事件)
  • 一个observable触发了一个事件,并且该observable与| async一起使用| async 在视图/模板中| async
  • 通过调用markForCheck()对组件进行“标记”以进行检查–可以在组件逻辑或某些后代逻辑中调用此组件(有关此内容,请参见下文)

如果未“标记” OnPush组件,则将不会检查该组件是否已更改, 也不会检查其任何后代 (无论他们使用的更改检测策略如何)。 因此,如果组件G使用默认的更改检测策略,而父组件C使用OnPush ,则如果未将C标记为检查,则也不会检查G。

您可以使用markForCheck()手动标记OnPush组件。 此方法还将标记其所有祖先直到根组件。 之所以必须这样做,是因为更改检测总是从根开始的,并且为了使更改检测返回到“已标记”的组件,Angular必须确保链/树上的任何其他OnPush组件也都位于标记。 否则,更改检测将永远不会使其退回到该组件。

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


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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM