https://stackblitz.com/edit/angular-xpamld
Question: Can someone help me understand why my prototype's changeDetection: ChangeDetectionStrategy.OnPush
still allows me to update the inner value name
? If this is not what ChangeDetectionStrategy.OnPush
suppose to prevent, what should it be doing?
app.component.ts:
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent {
public name = 'Angular 5';
public changeName() {
this.name = 'Outer';
}
}
app.component.html:
<hello name="{{ name }}"></hello>
<button (click)="changeName()">Outter Change</button>
<p>{{name}}-- outer</p>
<p>
Start editing to see some magic happen :)
</p>
hello.component.ts:
@Component({
selector: 'hello',
template: `<h1>Hello {{name}}!</h1> <button (click)="changeName()">inner Change</button>`,
styles: [`h1 { font-family: Lato; }`],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HelloComponent {
@Input() name: string;
public changeName() {
this.name = 'Inner';
}
}
But with OnPush strategy, the change detector is only triggered if the data passed on @Input() has a new reference. This is why using immutable objects is preferred, because immutable objects can be modified only by creating a new object reference.
OnPush means that the change detector's mode will be set to CheckOnce during hydration. Default means that the change detector's mode will be set to CheckAlways during hydration.
Go to Inventory>>Devices. Select the devices in which you want to enable/disable change detection.
Introduction. By default, Angular 2+ performs change detection on all components (from top to bottom) every time something changes in your app. A change can occur from a user event or data received from a network request.
Because primitive datatype is immutable - if you change it, its reference also changes, so ChangeDetectorRef
of your component knows it must detect changes (because OnPush
looks for references changes, not data mutations in arrays, objects). If you want to avoid that on primitives, you can manually deactivate/activate this on ChangeDetectorRef instance with detach()
/ reattach()
:
import { ChangeDetectorRef } from '@angular/core';
export class HelloComponent {
@Input() name: string;
constructor(private ref: ChangeDetectorRef) {}
public changeName() {
this.ref.detach();
this.name = 'Inner';
}
}
The default change detection strategy is to be conservative and check all its bindings for something that might have changed. Typically, a change detection cycle is triggered whenever an [input] changes, or an (event) occurs from any component.
By changing a component's change detection strategy to OnPush, Angular only checks for updates when the component's inputs have actually changed. This allows Angular to be more efficient with change detection by allowing entire sub-trees to be skipped during change detection.
Here is a good article on it: https://vsavkin.com/immutability-vs-encapsulation-90549ab74487
Some points to help with the understanding is:
OnPush
then during change detection, it will skip a component's entire sub-tree if the inputs have not changed.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With