4
  • parent component has one child component(child1)
  • child1 component has an input property person and OnPush changeDetection strategy
  • inside of child component, use settimeout in ngOnInit to mutable change person.

    • normally dom view will not update because of the onPush strategy
    • however if I use event emitter to emit this mutable change to its parent which in turn change the property binding(mutable), the view gets update.

So my question is here, will event emitter trigger view check?(change detection). Thanks!

parent component

@Component({
  selector: 'app-root',
  template: '<app-child1 [person]="person", (changOnPerson)="onPersonChange($event)">',
})
export class AppComponent {
  person: Person = {
    name: 'Alex',
    age: 20
 };
 constructor() {
 }
 onPersonChange($event) {
    this.person = $event.change;
  }
}

child1.compnent

@Component({
  selector: 'app-child1',
  template: '{{person | json}}',
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class Child1Component implements onInit {
  @Input() person: Person;
  @Output() changOnPerson = new EventEmitter();
  constructor() { }

  ngOnInit() {
    setTimeout(() => {
      this.person.name += ' ,abc';

      // core code here !
      this.changOnPerson.emit({ change: this.person });
    }, 2000);
  }
}

2 Answers 2

2

Mostly from observations, in Angular 15

  • After the function passed to setTimeout() is run, there is a change detection cycle at the top of the tree (a 'tick', I guess). This is still true when using OnPush. However, in this situation, this does not necessarily mean change detection will reach the view of the component which setTimeout() was called from.
  • When an EventEmitter has a handler/listener registered, calling emit will result in the views being marked dirty up to the root (markForCheck()-style).
  • As a result, if you emit a signal within a function whose execution is deferred via setTimeout(), and the parent component has registered a handler for that signal, you will have a change detection cycle for your component after the function is run.

Remarks about investigating change detection

  • When you inject NgZone in your component, you can wrap the call to setTimeout() in a function passed to this.zone.runOutsideAngular() to bypass the change detection cycle.
  • If you want to know if/when change detection runs for a component that has a child component, you can monitor the execution of ngDoCheck() on that child component. It is run for each change detection cycle of the (parent) component.
Sign up to request clarification or add additional context in comments.

Comments

0

I don't think it will as EventEmitter is an Observable, thus I don't think it is wrapped in NgZone.

Although don't rely on Change Detection defaults if possible. Just use OnPush.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.