考虑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
上的检测开始并仅影响F
和G
?
答案 0 :(得分:2)
更改检测是否运行
这取决于。默认情况下,更改检测将在每个异步事件(以及由Zone.js进行猴子修补的每个异步事件)之后运行,从组件树的顶部/根开始,然后以深度优先顺序访问每个节点一次。所以A-B-D-E-C-F-G(不是A-B-C-D-E-F-G,它将是广度优先的顺序)。
但是,如果您对组件G禁用了更改检测(请参阅detach()
),则单击处理程序运行后将不会运行更改检测。
更改检测是否在所有节点中运行
再次,这取决于。默认情况下,是,检查每个节点。
但是,组件可以从更改检测器树中分离(正如我刚才提到的),或者可以将它们配置为使用OnPush
更改检测策略。如果某个组件使用OnPush
,则只会检查是否标记了&#34;&#34;通过以下条件/事件之一进行检查:
| async
一起使用markForCheck()
进行检查 - 这可以在组件逻辑中调用,或者在某些后代逻辑中调用(更多关于此内容)如果OnPush
组件未标记为&#34;,则不会检查该组件的更改,也不会检查其任何后代(无论改变他们正在使用的检测策略)。因此,如果组件G使用默认的更改检测策略,但父组件C使用OnPush
,如果C未标记为要检查,则G也不会被选中。
您可以使用OnPush
手动标记markForCheck()
组件。此方法还会将其所有祖先标记为根组件。它必须这样做,因为变化检测始终从根...开始...并且为了使变化检测返回到标记为&#34;组件,Angular必须确保链/树上的任何其他OnPush
组件也被标记。否则,更改检测将永远不会使其返回到此组件。
OnPush
通常是一个不错的选择(即,他们不会从服务中获取数据。)
默认情况下,更改检测始终从根组件开始。但是,如果您手动调用detectChanges()
,它将只检查当前组件及其后代。