我正在使用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