Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | 1x 1x 3x 3x 4x 1x 1x 1x 1x 1x | import { Injectable, ChangeDetectorRef } from '@angular/core';
/**
* Service that optimizes change detection calls by ensuring that `detectChanges()`
* is only executed once per execution cycle, even if `update()` is called multiple times.
*
* This service is useful for preventing unnecessary re-rendering of Angular components,
* improving performance and efficiency.
*
* @example
* // Providing ViewRenderer in a Component
* import { Component, ChangeDetectorRef } from '@angular/core';
* import { ViewRenderer } from '../services/view-renderer.service';
*
* @Component({
* selector: 'app-example',
* template: `<button (click)="increment()">Increment</button><p>{{ counter }}</p>`,
* providers: [
* {
* provide: ViewRenderer,
* useFactory: (cdRef: ChangeDetectorRef) => new ViewRenderer(cdRef),
* deps: [ChangeDetectorRef]
* }
* ]
* })
* export class ExampleComponent {
* counter = 0;
*
* constructor(private renderer: ViewRenderer) {} // Inject ViewRenderer with ChangeDetectorRef
*
* increment() {
* for (let i = 0; i < 10; i++) {
* this.counter++;
* this.renderer.markForCheck(); // `detectChanges()` will only be called once per cycle
* }
* }
* }
*/
@Injectable()
export class ViewRenderer {
private _scheduled = false;
/**
* Constructs the `ViewRenderer` service and injects the `ChangeDetectorRef`.
*
* @param change - The `ChangeDetectorRef` instance for managing change detection in Angular.
*/
constructor(private change: ChangeDetectorRef) {
// nothing to do
}
/**
* Returns the `ChangeDetectorRef` instance associated with this service.
*
* @returns The `ChangeDetectorRef` instance used for change detection.
*
* @example
* // Accessing ChangeDetectorRef from ViewRenderer
* const cdRef = this.renderer.cdref;
* cdRef.markForCheck();
*/
get cdref(): ChangeDetectorRef{
return this.change;
}
/**
* Schedules a change detection cycle. If called multiple times in the same execution cycle,
* it ensures that `detectChanges()` is only executed once.
*
* This method improves performance by avoiding redundant calls to `detectChanges()`.
*/
markForCheck(force = false): void {
if (!this._scheduled) {
this._scheduled = true;
if (force){
this.change.detectChanges();
this._scheduled = false;
}
else E{ // delay change detection
Promise.resolve().then(() => {
this.change.detectChanges();
this._scheduled = false;
});
}
}
}
}
|