2017-07-24 148 views
1

阅读关于Zone.JS并更改检测过程,在源代码中Zone.JS通知Angular关于变化,它通过在所有组件上传播检查来从上到下运行第一个组件,但在我的测试中,我有一个不同的行为。Angular OnPush组件,当触发事件在视图中角度强迫markForCheck自动?

检查我的样本:

http://plnkr.co/edit/QPHBQ7cYg9JFZr2oVnGZ?p=preview

样品具有以下结构:

<app-component> 
    <child-component> 
     <grand-child-component> 

他们互相嵌套,他们都没有@input属性,所有的人是OnPush,并且它们在视图中显示简单的值,如:

查看:

{{getComponentValue}}

打字稿

value = "app component"; 

get getComponentValue() { // <-- ES6 get to log when Angular check 
    console.log('change detection checking here in component app-component') 
    return this.value; 
} 

可以在样品中检查这个代码。

当应用程序被启动,我们可以看到日志:

check component app 
check component child 
check component grand child 

很酷,但是,现在我们如果盛大孩子触发事件的想象吗?

在盛大的孩子

<button (click)="undefined"> {{getComponentValue}} </button> 
<!-- (click)="undefined" cria um inscrito no evento. --> 

更改视图我们有日志:

check component app 
check component child 
check component grand child 

我预计:当我点击了盛大子按钮,该事件将开始在应用程序组件, 但是,由于所有这些都是OnPush,从来没有事件会到达盛大的孩子,因为没有@Input被更改,我将不得不手动调用markforcheck或detectchanges,但上面的代码看起来像我调用了markforcheck。

我在grand-child组件中调用了settimeout,interval和具有可观察对象的事件,并且它们都没有调用更改(检查grand-component ts),仅在视图中(单击)检查被调用...

验证发生在你可以测试的地方:在孩子或应用程序组件中,你可以添加setInterval,增加一个值 你可以检查视图,认识到只有当grand-child触发(单击)你的祖先的价值更新!

我意识到:setTimeout的,间隔,或与观测组件和的TS内的事件时,该组件是OnPush 事件在应用程序组件启动,但它们不是“强行传播”,因为在没有变化@Input,但是当我们在视图中添加事件时,就像(点击)一些 他们通过模拟markForCheck强制的方式,实际发生了什么?

当我们在视图中添加一个事件时,引擎盖下的Angular强制使用markForCheck();对组件? 因为这似乎是发生。

回答

2

是的,这是由设计:一个绑定的事件triggers markForCheck内部

export function dispatchEvent(
    view: ViewData, nodeIndex: number, eventName: string, event: any): boolean { 
    const nodeDef = view.def.nodes[nodeIndex]; 
    const startView = 
     nodeDef.flags & NodeFlags.ComponentView ? asElementData(view, nodeIndex).componentView : view; 
    markParentViewsForCheck(startView); // <== this line 
    return Services.handleEvent(view, nodeIndex, eventName, event); 
} 

参见

+0

谢谢你的回复!很酷,在你的链接中,你说过4个用OnPush调用检测的情况,但是你还没有忘记detectChanges()?这会引发他和他的孩子的变化,对吗? –

+0

@GustavoCosta它不会触发onPush策略的变化。 https://plnkr.co/edit/O65ZZ8147J6eDVjreXaO?p=preview – yurzui

+0

使用detectChanges,检查仅在组件中使用绑定进行,并且您的子项和@Input属性将不会被检查,是吗? –