ChangeDetectorRef • Angular

The following examples demonstrate how to modify default change-detection behavior to perform explicit detection when needed.

Use markForCheck() with CheckOnce strategy

The following example sets the OnPush change-detection strategy for a component (CheckOnce, rather than the default CheckAlways), then forces a second check after an interval.

@Component({  selector: 'app-root',  template: `Number of ticks: {{ numberOfTicks }}`,  changeDetection: ChangeDetectionStrategy.OnPush,})class AppComponent {  numberOfTicks = 0;  constructor(private ref: ChangeDetectorRef) {    setInterval(() => {      this.numberOfTicks++;      // require view to be updated      this.ref.markForCheck();    }, 1000);  }}

Detach change detector to limit how often check occurs

The following example defines a component with a large list of read-only data that is expected to change constantly, many times per second. To improve performance, we want to check and update the list less often than the changes actually occur. To do that, we detach the component's change detector and perform an explicit local check every five seconds.

class DataListProvider {  // in a real application the returned data will be different every time  get data() {    return [1, 2, 3, 4, 5];  }}@Component({  selector: 'giant-list',  template: ` <ul>    @for (d of dataProvider.data; track $index) {      <li>Item {{ d }}</li>    }  </ul>`,})class GiantList {  constructor(    private ref: ChangeDetectorRef,    public dataProvider: DataListProvider,  ) {    ref.detach();    setInterval(() => {      this.ref.detectChanges();    }, 5000);  }}@Component({  selector: 'app',  providers: [DataListProvider],  imports: [GiantList],  template: `<giant-list />`,})class App {}

Reattaching a detached component

The following example creates a component displaying live data. The component detaches its change detector from the main change detector tree when the live property is set to false, and reattaches it when the property becomes true.

class DataProvider {  data = signal(1);  constructor() {    setInterval(() => {      this.data.set(2);    }, 500);  }}@Component({  selector: 'live-data',  template: 'Data: {{dataProvider.data()}}',})class LiveData {  live = input.required<boolean>();  constructor(    private ref: ChangeDetectorRef,    public dataProvider: DataProvider,  ) {    effect(() => {      if (this.live()) {        this.ref.reattach();      } else {        this.ref.detach();      }    });  }}@Component({  selector: 'app',  providers: [DataProvider],  imports: [FormsModule, LiveData],  template: `    Live Update: <input type="checkbox" [(ngModel)]="live" />    <live-data [live]="live"></live-data>  `,})class App1 {  live = true;}