【问题标题】:Angular 2 forms + OnPushAngular 2 形式 + OnPush
【发布时间】:2017-02-02 21:29:24
【问题描述】:

我正在编写一个 Angular 2 应用程序,出于性能原因,我尝试在任何地方使用 ChangeDetectionStrategy.OnPush。我有一个复杂的组件,它需要 OnPush 才能顺利工作,其中包含另一个显示表单的组件(使用 FormBuilder 创建)。我现在注意到,当我点击一个滑块时,它的内部值会更新(即 form.value),但滑块组件不会可视化这个新值,即它卡在旧位置。

我解决此问题的第一个想法是将叶组件的更改检测策略设置为 DEFAULT,但这没有效果,因为显然这也需要更改其父组件的更改检测策略(这在我的应用程序中是不可能的) .

然后我想出了这个主意:

@Component({
   ...
})
class MyComponent implements OnInit {
  constructor(private zone: NgZone) {}

ngOnInit() {
  INIT_FORM();

  this.form.valueChanges
    .subscribe(() => {
      this.zone.run(() => {});
    });
  }
}

但它没有效果。

是否有可能使 angular 2 表单在使用 OnPush 的组件中工作?

【问题讨论】:

  • 您需要确保每次发生相关更改时,您的组件使用的@Inputs 中至少有一个OnPush 具有新的引用。关于使整个应用程序使用OnPush 的一个很好的指南可以找到here

标签: angular angular2-forms angular2-changedetection


【解决方案1】:

我自己没有测试过,但手动调用变更检测可能会做你想做的事:

@Component({
   ...
})
class MyComponent implements OnInit {
  constructor(private cdRef: ChangeDetectorRef) {}

ngOnInit() {
  INIT_FORM();

  this.form.valueChanges
    .subscribe(() => {
      this.cdRef.detectChanges();
    });
  }
}

【讨论】:

  • 感谢您的回答,可惜这并没有解决问题,滑块还是卡住了。你还有什么想法吗?
  • 一个 Plunker 复制可能会有所帮助
  • 我创建了一个 plunker:plnkr.co/edit/oVIoDua2olC6i56rzDcw?p=preview
  • 啊,我找到了让它工作的方法:cdRef.markForCheck() 成功了! (来自这里:forum.ionicframework.com/t/…
  • 别忘了退订。它可能会导致内存泄漏。
【解决方案2】:

让我回复我在其他帖子中一直在回答的问题,您可以做得更好!如果可行,请告诉我:

当您使用响应式表单时,您可以使用一种非常酷的方法,称为updateValueAndValidity();触发更改检测。

private changeControlValue(control, value: number) {
    control.setValue(value);
    control.updateValueAndValidity();
  }

您也可以在更新添加到表单的验证器时使用此方法,例如:

this.control.setValidators([Validators.required, Validators.minLength(5)]);
control.updateValueAndValidity();

这应该可以解决问题!我认为这是针对 ng-model 使用响应式表单或表单控件的最佳尝试之一。

我不建议在您的表单中使用 valueChanges,因为您可能会忘记取消订阅并造成内存泄漏,即使您记得创建此流程可能很乏味。

请记住,当使用 onPush 更改检测时,Angular 只会将三件事检测为更改:

1- 输入和输出。 2- 用户可以执行的 Html 事件,例如(单击)。 3- 订阅等异步事件。

希望对你有所帮助!

【讨论】:

    猜你喜欢
    • 2017-09-28
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    • 2016-10-18
    • 2019-06-17
    • 1970-01-01
    • 1970-01-01
    • 2017-08-08
    相关资源
    最近更新 更多