我有一个 Angular2 表单(例如)
<form id="myLovelyForm" name="myLovelyForm" #myLovelyForm="ngForm">
<label [attr.for]="myLovelyCheckbox">
<input [attr.id]="myLovelyCheckbox" type="checkbox"
[(ngModel)]="myLovelyCheckbox">
<span class="myLovelyCheckbox">myLovelyCheckbox</span>
</label>
</form>
还有一个动画,如果表单脏了,应该启动:
<div
id="myLovelyNotification"
class="myLovelyNotification"
[@notification]="myLovelyForm.form.dirty">
.....
.....
</div>
如果我设置 [@notification] = true,动画可以正常工作,但如果我触摸表单并更改元素,我的
myLovelyForm.dirty
不会触发。
如果 @notification 为 false,则动画停止,即,如果之前选中了复选框,并且我错误地取消选择它并再次选择它,则表单不是原始(触摸)但不再是脏的,因此动画应该停止。如果我手动设置@notification = false,它就可以正常工作。
最大的问题是:如何以正确的方式检测/观察 angular2 形式的“脏状态”?
简单-
@ViewChild('f') templateForm: any;
ngOnInit() {
this.templateForm.valueChanges.subscribe((value: any) => {
if (this.templateForm.dirty) {
console.log('template form dirty - yes: ', value);
} else {
console.log('template form dirty - no: ');
}
});
}
您的模板包含:
<form #f="ngForm" (ngSubmit)="save(f)>
...
</form>
然而,这仍然使用模板表单,它们确实可以帮助弥合与 Angular1 应用程序的差距。 模型驱动表单是 Angular 2 的方法,除了真正的基本应用程序之外,其他任何东西都可以使用模型驱动表单。 参见示例:
您可以订阅表单更改:
this.physicalForm.valueChanges
.map((value) => {
return value;
})
.subscribe((value) => {
if(this.selectedPhysical.weight != this.physicalForm.value.weight) {
this.selectedPhysical.weight = this.physicalForm.value.weight;
}
this.isDirty == this.physicalForm.touched;
});
如果此事件触发,那么您就知道您的表单已脏。
这是我实际应用程序的示例(nut.abbr 是 formcontrolName):
ngOnInit() {
for (let nut of this.userSettings.nutrientData) {
this.foodSettingsForm.controls[nut.abbr].valueChanges
.subscribe(v => { console.log("value: ", v); this.completeValueChange(nut.abbr, v); });
}
}
completeValueChange(field: string, value: boolean) {
this.isChanged = true;
Nutrient.updateNutrient(field, value, this.userSettings.nutrientData);
}
现在,Angular 18 FormControl 具有
events
Observable,您可以在其中监听 PristineChangeEvent
等事件
this.form.events.pipe(takeUntilDestroyed()).subscribe((event) => {
if (event instanceof PristineChangeEvent) {
console.log('form pristine change ', event.pristine);
console.log(this.form.pristine); // same same
}
});