Does `changeDetection: ChangeDetectionStrategy.OnPush` in angular2 only works in one direction: top->bottom?

后端 未结 2 2042
走了就别回头了
走了就别回头了 2021-01-14 18:12

Consider this plunker

import {Component, OnInit, Input, OnChanges, DoCheck, ChangeDetectionStrategy, EventEmitter} from \'angular2/core\'

@Component({
  sel         


        
相关标签:
2条回答
  • 2021-01-14 18:41

    I know it has been a while, but i came across a similar problem. Hence i wanted to stress on the fact that OnPush does not always change the way parent and child component communication works. If the child component's @Input property is an object (reference type) then the only way OnChanges is triggered on the child is when the reference changes (new object is created) regardless of OnPush. OnPush makes more sense for template binding, requesting angular to do value equality or just compare references. Please do correct me if i was wrong.

    0 讨论(0)
  • 2021-01-14 18:49

    According to Savkin's blog post (well, it is buried in a comment to @vivainio),
    with OnPush, Angular will only check the component for changes (i.e., check the template bindings) when

    • any of its input properties changes
    • it fires an event (e.g., a button click)
    • an observable fires an event [Note that this is not entirely correct. The observable needs to use | async in the view/template in order for change detection to run. See comments on this answer for more info.]

    If any of those conditions are met, Angular will also "mark" all components up the tree to the root component as needing change detection. It will then run change detection. All of the ancestor components, even if they are configured for the OnPush strategy will be checked for changes, since they are currently "marked".

    This explains why the views for the Parent/App and Child1 components get updated as a result of an event firing in component Child11.


    This "mark up the tree" functionality is by design, and for the exact reason/scenario you show in your sample code – i.e., a component changes some application data, and ancestor components have data bindings for that same data in their views. How does Angular ensure the views will get updated? It has to "mark" all ancestors up to the root component so that when change detection runs, all of those components will be checked.

    Note that this doesn't cover all scenarios though. Suppose that the changed application data is also present in a component view in some other, unrelated, "branch" of the component tree, and that branch uses OnPush. That component view will not get updated.

    0 讨论(0)
提交回复
热议问题