如果在父级和子级组件中进行设置,则ChangeDetectionStrategy OnPush不起作用

时间:2018-08-10 07:21:21

标签: angular typescript angular-components

我有两个组成部分。

在两个组件中,我都设置了$('.edit-definition').each(function (i, block) { hljs.highlightBlock(block); block.innerHTML = block.innerHTML .replace(/(&lt;\/\s)/g, "<span class='hljs-red'>$1</span>") //spaces in the start of tag .replace(/(\s+>|\s+&gt;)/g, "<span class='hljs-red'>$1</span>") //spaces in the end of tag .replace(/(http\s|https\s|\s+\/\/\s+|\s+\\\\\s+|\s+\/\s+|\s+\\\s+)/g, "<span class='hljs-red'>$1</span>") //spaces in urls });

AComponent(子级)

ChangeDetectionStrategy OnPush

和AppComponent(父级)。

@Component({
  selector: 'app-a',
     ... ,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class AComponent {

  private _value: string;

  @Input()
  set value(v: string) {
    console.log(`set value : ${v}`);
    this._value = v;
  }

  get value() {
    return this._value;
  }

}

Appcomponent(父级)模板

@Component({
    ... ,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {

  value: string = "0";

  toClick(event) {

    // set value before request to server
    // for example to set a progress spinner    
    this.value = "1";

    setTimeout(() => {
      console.log('connected to server');

      //set value after request to server
      this.value = "2";
    }, 500);
  }

}

如果我单击Acomponent,将设置<app-a [value]="value" (click)="toClick()"></app-a> 值,但未设置"1"。 (您可以在控制台上看到它)

如果我在"2"(父级)的“默认”中更改了ChangeDetectionStrategy, 它可以正常工作。

有人可以解释这种行为吗?

DEMO

1 个答案:

答案 0 :(得分:2)

使用OnPush策略,更改检测仅在模板上发生事件时才起作用,在您的情况下,toClick@Input参数已更改。在事件处理程序中,您有一个异步回调函数(setTimeout),该函数已经从事件处理程序中退出。因此,您需要通过回调函数手动运行更改检测。

您可以注入ChangeDetectorRef并使用markForCheck函数来手动运行更改检测。

检查Stackblitz example