【问题标题】:Angular 2 OnPush change detection for dynamic componentsAngular 2 OnPush 动态组件的变化检测
【发布时间】:2017-06-07 10:41:57
【问题描述】:

我有一个 Angular 组件,它在自身内部动态创建各种其他类型的组件。它通过OnChanges 钩子将自己的属性绑定到子组件@Input 属性。

当子组件的更改检测设置为默认值时,此绑定可以正常工作。然后检测到新的输入并更新组件模板。

但是,当更改检测为 OnPush 时不起作用,则未检测到更改。我认为应该检测到更改,因为一个新的不可变对象(字符串)被分配给组件@Input 属性。

这里有一个 plunker 来演示: https://plnkr.co/edit/0wHQghtww2HXVbC27bC1

如何让这个父到动态子属性绑定与 ChangeDetectionStrategy.OnPush 一起使用?

【问题讨论】:

  • 对于任何感兴趣的人,这里是相关的 GitHub 问题,其中包含有关为什么 OnPush 更改检测对动态组件的工作方式不同的更多信息 - github.com/angular/angular/issues/14087
  • 这个问题解决了吗?

标签: angular angular2-changedetection


【解决方案1】:

OnPush 组件的可能解决方法是将 setter 与 cdRef.markForCheck() 一起使用:

change-detection-onpush.component.ts

@Component({
  selector: 'app-change-detection-onpush',
  template: `
    <div>
      ChangeDetectionStrategy.OnPush: {{ message || '[blank]' }}
    </div>`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChangeDetectionOnPushComponent implements IMyComponent {
  private _message: string;

  constructor(private cdRef: ChangeDetectorRef) {}

  set message(val: string) {
    this.cdRef.markForCheck();
    this._message = val;
  }

  get message() {
    return this._message;
  }
}

Modified Plunker

【讨论】:

  • 看来,Plunker 不工作,是否可以将工作代码移至 Stackblitz。
  • @Cegone 请看这个plunker plnkr.co/edit/NJRoUOvfrI8dQkWRoLcM?p=preview
  • 谢谢@Yurzui,它对我有用。实际上,我错过了这部分, set message(val: string) { this.cdRef.markForCheck(); this._message = val;但是,当我们尝试 Dump Component 时,这样可以吗?因为我们需要在 Constructor 中注入 ChangeDetectorRef。
  • 如果 ChangeDetectionOnPushComponent 组件中有很多可用的输入变量,我是否需要将 markForCheck() 放入所有输入变量中?
猜你喜欢
  • 2017-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-23
  • 2018-06-14
  • 2018-07-10
  • 2018-09-06
相关资源
最近更新 更多