为什么changeDetectionStrategy.OnPush不会在@Input属性更改中更新,但更新@Output会触发属性更改?

2024-01-02

考虑一下这个plunker https://plnkr.co/edit/K1tKdpTm3YZ7T9fETdXs?p=preview

Grandchild Component

<button (click)="back2click()"></button>

@Input() from2;
@Output()
back2 = new EventEmitter<any>();

back2click() {
   this.back2.emit('hi');
}

Child Component

changeDetection: ChangeDetectionStrategy.OnPush,

<my-app-n2 [from2]="from1" (back2)="handleback2($event)"></my-app-n2>

@Input() from1;
@Output() back1 = new EventEmitter<any>();

handleback2() {
    this.back1.emit('hi')
}

Parent Component

<my-app-n1 [from1]="from" (back1)="handleback1($event)"></my-app-n1>
handleback1 () {
    this.from.name = 'handline4';
}

我看到当button被点击

back2click -> emit -> handleback2 -> emit -> handleback1 
    -> attribute is updated -> all child view are updated

这很令人困惑,因为我预计只有父视图会得到更新changeDetection: ChangeDetectionStrategy.OnPush,是子组件中的配置。

我想我错过了一些东西,有人能指出我正确的方向吗?

Thanks


所有本机事件都会标记根组件的路径以供检查一次。这里的模板是Grandchild Component你正在使用本机click event:

<button (click)="back2click()"></button>

因此,组件的层次结构被标记为检查一次。

   Root Component -> ViewState.ChecksEnabled = true
     |
    ...
     |
   Parent  -> ViewState.ChecksEnabled = true
     |
     |
   Child  (onPush)  -> ViewState.ChecksEnabled = true
     |
     |
   Grand child (event triggered here) -> markForCheck() -> ViewState.ChecksEnabled = true

有关变更检测的最全面的解释,请阅读:

  • 关于 Angular 中的变更检测您需要了解的一切 https://blog.angularindepth.com/everything-you-need-to-know-about-change-detection-in-angular-8006c51d206f

要了解更多信息markForCheck see 这个答案 https://stackoverflow.com/a/45396740/2545680并阅读这篇文章:

  • 如果你认为ngDoCheck表示您的组件正在接受检查 — 阅读本文 https://blog.angularindepth.com/if-you-think-ngdocheck-means-your-component-is-being-checked-read-this-article-36ce63a3f3e5
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么changeDetectionStrategy.OnPush不会在@Input属性更改中更新,但更新@Output会触发属性更改? 的相关文章

随机推荐