响应式表单控件触发更改检测

问题描述

Reactive FormControl 元素在输入值改变时触发 ChangeDetection。我添加OnPush 策略,但它仍然运行 ChangeDetection

@Component({
  selector: 'app-server-input',templateUrl: './server-input.component.html',styleUrls: ['./server-input.component.css'],changeDetection: ChangeDetectionStrategy.OnPush
})

FormControl 指令是触发 ChangeDetection 的指令。当输入更改时,我如何停止运行 ChangeDetection

serverName: FormControl = new FormControl();

这是我在 StackBlitz 上的 code

注意:这里要注意的一件事是,如果您单击按钮,则会调用 ngDocheck,因此我使用事件管理器来停止更改检测。

解决方法

input 始终运行。不管你使用什么策略。请参阅 https://indepth.dev/posts/1131/if-you-think-ngdocheck-means-your-component-is-being-checked-read-this-articleWhy do we need `ngDoCheck`

我看不出有什么理由让您想知道更改检测运行的时间和原因。如果您想对更改进行某些操作,只需在您的输入中使用 setter:

ngDoCheck
,

我已经分叉并更新了您的代码:https://stackblitz.com/edit/child-component-2bstm4?file=app/app.component.ts

  ngOnInit() {    
    this.zone.runOutsideAngular(() => (
      this.serverName = new FormControl(),this.cd.detach()
      )
    );
  }
,

为了防止每次用户与输入字段交互时 angular 运行变化检测,您应该分离变化检测器。 您需要注入 ChangeDetectorRef 并调用其分离方法

  constructor(private cd: ChangeDetectorRef) {}
  ngOnInit() {
    this.cd.detach();
  }

将不再为此组件及其子组件自动运行更改检测。 当您需要触发变更检测时,您可以调用 ChangeDetectorRef 上的 detectChanges 方法。

例如,这将每 5 秒触发一次更改检测。

  ngOnInit() {
    this.cd.detach();
    setInterval(() => this.cd.detectChanges(),5000);
  }
,

在下面提到的链接中,有一个选项可以禁用表单控件上的更改检测

disable form control