Why do we need `ngDoCheck`

前端 未结 3 1541
臣服心动
臣服心动 2020-12-07 10:46

I can\'t seem to figure out why I need ngDoCheck lifecycle hook other than for simple notification, particularly how writing code inside of it makes a differenc

3条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-07 11:04

    The DoCheck interface is used to detect changes manually which the angular change detection have overlooked. A use could be when you change the ChangeDetectionStrategy of your component, but you know that one property of an object will change.

    It's more efficient to check for this one change, than to let the changeDetector run through your entire component

    let obj = {
      iChange: 'hiii'
    }
    

    If you use obj.iChange inside your template, angular will not detect it if this value changes, because the reference of obj itself doesn't change. You need to implement an ngDoCheck to check if the value has changed, and call a detectChanges on your component's changeDetector.

    From the angular documentation about DoCheck

    While the ngDoCheck hook can detect when the hero's name has changed, it has a frightful cost. This hook is called with enormous frequency — after every change detection cycle no matter where the change occurred. It's called over twenty times in this example before the user can do anything.

    Most of these initial checks are triggered by Angular's first rendering of unrelated data elsewhere on the page. Mere mousing into another input box triggers a call. Relatively few calls reveal actual changes to pertinent data. Clearly our implementation must be very lightweight or the user experience will suffer.

    tested example

    @Component({
       selector: 'test-do-check',
       template: `
          
    `, changeDetection: ChangeDetectionStrategy.OnPush }) export class TestDoCheckComponent implements DoCheck, OnInit { public obj: any = { changer: 1 }; private _oldValue: number = 1; constructor(private _changeRef: ChangeDetectorRef){} ngOnInit() { setInterval(() => { this.obj.changer += 1; }, 1000); } ngDoCheck() { if(this._oldValue !== this.obj.changer) { this._oldValue = this.obj.changer; //disable this line to see the counter not moving this._changeRef.detectChanges(); } } }

提交回复
热议问题