#Problem with Change Detection

8 messages · Page 1 of 1 (latest)

dawn jackal
#

I have main App Component, it is empty and change detection i set to OnPush.

I have another component which is placed inside App Component and this component do NOT have change detection set, so it's default.

In this component I have two simple strings, when I click on the text I want to change it.

text1 is changing as expected.

text2 is not changing in the view (it should change after modal is closed)

I would like to know the reason why text2 is not updating. When I remove OnPush from main App Component it works perfectly.

I know how to fix it, but I would like to know the reason why it is not updating, for me it should because ExampleComponent is not OnPush.

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  template: '<app-example></app-example>',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {}

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.scss'],
  template: '<div (click)="changeText1()">{{ text1 }}</div> <div (click)="changeText2()">{{ text2 }}</div>'
})
export class ExampleComponent {
  text1 = 'text1';
  text2 = 'text2';

  changeText1() {
    text1 = 'text1 changed';
  }

  changeText2() {
    let dialogRef = dialog.open(ExampleModal);

    dialogRef.afterClosed().subscribe(() {
      text2 = 'text2 changed';
    });
  }
}
sharp flower
#

I'm not sure how app component can be both empty and containing the example component. But anyway, since app component is OnPush, and since CD always go from the root to the children, if app component is not checked, then none of its descendants will be checked.

dawn jackal
#

Yeah, it's not empty, I meant only <app-example> inside. OK, I understand what you said, but why text1 is changing properly in the view, that's because of the click event and text2 is not changing beacuse it's changing after something and not directly after some event like click?

sharp flower
#

Yes.

#

You shouldn't make the app component OnPush, IMO. There's nothing to check anyway in the component, so you gain nothing, but you're forcing each and every component to support OnPush by doing so.

dawn jackal
#

so changeText1() call causes AppComponent to trigger CD (because text1 is changed directly) and changeText2() not?

It's just an example. My AppComponent in real project is bigger and there are some things to check.

dawn jackal
#

And last question, theoretically if I have OnPush inside main AppComponent I don't have to set it to any children? Because OnPush on AppComponent forces me to use everywhere in children observables/signals/inputs/events to trigger change?

sharp flower
#

Yes, you should still set them. Because you still don't want to check some children even when the parents are checked. OnPush is best used on leaf components that display stuff and are repeated many times on the page.