5

我正在编写一个 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 的组件内工作?

4

2 回答 2

6

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

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

ngOnInit() {
  INIT_FORM();

  this.form.valueChanges
    .subscribe(() => {
      this.cdRef.detectChanges();
    });
  }
}
于 2016-09-25T16:51:20.507 回答
1

让我回复一下我在其他帖子上一直在回答的问题,你可以做得更好!,让我知道这是否有效:

当您使用响应式表单时,您可以使用一个非常酷的方法,称为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- 订阅等异步事件。

我希望我帮助你!

于 2020-04-03T09:43:30.523 回答