角度形式变化检测

gfe*_*els 2 rxjs ionic-framework ionic3 angular angular-forms

我正在使用 Angular 表单,并且我想使用它们的内置更改检测在我的应用程序中实现一个功能。当用户单击按钮时,如果他/她对表单进行了任何更改,他/她应该只会看到一个对话框。

我有 changesMade 变量:

private changesMade: boolean;
Run Code Online (Sandbox Code Playgroud)

这是我的形式的 TS 代码:

this.carForm = new FormGroup({
        name: new FormControl('', [
            Validators.required,
            Validators.pattern('[a-zA-Z ]*'),
            Validators.minLength(1),
            Validators.maxLength(10)
        ])});
Run Code Online (Sandbox Code Playgroud)

这是我的表单的 HTML 代码:

<form [formGroup]="carForm">
        <ion-item>
          <ion-label  stacked>car name</ion-label>
          <ion-input type="text" [(ngModel)]="carname" formControlName="name"></ion-input>
        </ion-item>
</form>
Run Code Online (Sandbox Code Playgroud)

这是我的模拟(目前)服务调用,在我设置了绑定到输入的 carname 的值后,我订阅了表单更改

setTimeout(()=>{
  this.carname = "BMW";
  this.carForm.valueChanges.subscribe(val => {
  this.changesMade = true;
    });
}, 44)
Run Code Online (Sandbox Code Playgroud)

这里的问题是,即使我没有接触过表单,this.changesMade 也会被设置为 true。

注意:如果我在 ngAfterViewInit 中移动代码的 subscribe 部分,它仍然将 changesMade 设置为 true,即使我没有触摸输入:

  ngOnInit(){
    //simulated server call
    setTimeout(()=>{
      this.carname = "BMW";

    }, 44)
  }
      ngAfterViewInit(){
this.carForm.valueChanges.subscribe(val => {
      this.changesMade = true;
        });
    }
Run Code Online (Sandbox Code Playgroud)

我创建了一个STACKBLITZ 来演示这个问题。this.changesMade = true;仅当我实际触摸 UI 中的输入时,如何才能使其执行?

Kli*_* Ru 5

您以一种形式使用两种方法:

你需要选择一个。

这个具有反应形式的解决方案:

1.从模板中移除ngModel

<ion-input type="text" formControlName="name"></ion-input>
Run Code Online (Sandbox Code Playgroud)

2.增加rxjs /第一的更新changesMade一次和经销商退订

import 'rxjs/add/operator/first';
Run Code Online (Sandbox Code Playgroud)

3.从你的组件中移除 carName 属性并使用patchValue更新

ngOnInit() {
  //simulated server call
  setTimeout(() => {
    this.carForm.patchValue({ name: 'BMW' })
    this.carForm.valueChanges.first().subscribe(val => {
      this.changesMade = true;
    });
  }, 44)
}
Run Code Online (Sandbox Code Playgroud)

Stackblitz 示例