Angular 2形成+ OnPush

时间:2016-09-25 13:50:03

标签: angular angular2-forms angular2-changedetection

由于性能原因,我正在编写一个角度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(() => {});
    });
  }
}

但它没有效果。

是否有可能在使用OnPush的组件内使角度2表单工作?

2 个答案:

答案 0 :(得分:1)

未自行测试但手动调用更改检测可能会执行您想要的操作:

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

ngOnInit() {
  INIT_FORM();

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

答案 1 :(得分:1)

让我用我在另一篇文章中一直回答的内容作为回应,您可以做得更好!,请告诉我是否可行:

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

\\

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

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

这应该可以解决问题!我认为这是对ng模型使用反应形式或形式控件的最佳尝试之一。

我不建议在您的表单上使用valueChanges,因为您很容易忘记退订并造成内存泄漏,即使您记得创建此流程也可能很乏味。

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

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

希望我能帮助您!。