Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2+, will Event emitter trigger change detection?

  • 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);
  }
}
like image 609
好吃仙人 Avatar asked Oct 30 '25 13:10

好吃仙人


1 Answers

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.
like image 191
ghostinpeace Avatar answered Nov 01 '25 07:11

ghostinpeace



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!