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

我有changesMade变量:

private changesMade: boolean;


这是我的TS格式的代码:

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


这是我的以下形式的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>


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

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


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

注意:如果我在ngAfterViewInit中移动了代码的订阅部分,即使我没有按下输入,它仍会将changesMade设置为true:

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

    }, 44)
  }
      ngAfterViewInit(){
this.carForm.valueChanges.subscribe(val => {
      this.changesMade = true;
        });
    }


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

最佳答案

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


Reactive Forms
Template Forms


您需要选择一个。

该解决方案具有反应形式:

1.从模板中删除ngModel

<ion-input type="text" formControlName="name"></ion-input>


2,添加rxjs/first进行更新更改一次并自动退订

import 'rxjs/add/operator/first';


3.从您的组件中删除carName属性,并使用patchValue更新

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


Stackblitz example

07-24 09:17