<小时/> 似乎
form.dirty
在更改后不会对其值进行编辑,form.touched
似乎始终为false
,无论如何:dirty
为{{1} }},touched
是tetched。template.html
touched
component.ts
<form #form="ngForm" (ngSubmit)="handleSubmission($event, {}, form)">
...
<input
#input
type="text"
[name]="item.title"
[(ngModel)]="item.estimate"
(ngModelChange)="handleEstimateChange(item, item.estimate, input, form)"
/>
...
</form>
在TypeScript中,我去抖动 export class LeComponent {
@Input('data') public data: any;
public handleEstimateChange: Function;
constructor(private $: Sandbox) {
this.handleEstimateChange = $.debounce(this.handleEstimate.bind(this), (1000*0.2));
}
handleEstimate(item: any, estimate: number, input: HTMLInputElement, form: NgForm) {
if (!estimate) delete item.esitmate;
(this, item, estimate, input, form);
// Why does form.dirty never change back to pristine again???
}
}
处理程序,以便在我检查之前为Angular提供更改ngModelChange
值的机会。这是因为form.dirty
在ngModelChange
对象被修改之前被触发。
如果NgForm
,因为!estimate
,则将其重新设置为原始值estimate === ""
。在这种情况下,表单应该完全,就像任何用户输入发生之前一样。
但是,当我在评论正上方的行上添加断点并将undefined
输出到form.dirty
时, NgForm永远不会将console
更改回{{1 }}
是否可以确定表单是否与任何用户输入之前的完全一样?
显然,我可以编写自己的脏逻辑,但这并不意味着dirty
有点无用吗?我不得不失去一些东西,对吧?怎么可能脏并不意味着脏?
我已经看过其他一些SO问题 - 第一个问题类似,但绝对不是我要问的问题。他们在问这是故意 - 我不在乎;我想知道如何实现上述目标。
关闭,但没有雪茄:angular2 formcontrol stays dirty even if set to original value
Block routing if form is dirty [ Angular 2 ]
Angular 2 getting only the dirty values in a controlgroup
How do I programmatically set an Angular 2 form control to dirty?
Angular 2.x/4.x & bootstrap: patchValue does not alter dirty flag. Possible bug?
答案 0 :(得分:1)
使用模板驱动的表单和非常扁平的数据模型,我实现了这样:
private currentProduct: IProduct;
private originalProduct: IProduct;
get isDirty(): boolean {
return JSON.stringify(this.originalProduct) !== JSON.stringify(this.currentProduct);
}
get product(): IProduct {
return this.currentProduct;
}
set product(value: IProduct) {
this.currentProduct = value;
// Clone the object to retain a copy
this.originalProduct = Object.assign({}, value);
}
但这仅适用于非常简单的情况。
正如我在评论中所提到的,使用被动表单可以更灵活地管理与用户条目分开的数据模型。
答案 1 :(得分:0)
<form #form="ngForm" (ngSubmit)="handleSubmission($event, {}, form)">
...
<input
#input
type="text"
[name]="item.title"
[attr.name]="item.title"
[(ngModel)]="item.estimate"
(ngModelChange)="handleEstimateChange(item, item.estimate, input, form)"
/>
...
</form>
component.ts
export class LeComponent {
@Input('data') public section: any;
public handleEstimateChange: Function;
private resetFormControl = (input: HTMLInputElement, form: NgForm) => {
var name = input.name, control = form.controls[name];
control.reset();
// control.markAsPristine();
// control.setValue(undefined);
// control.updateValueAndValidity();
};
constructor(private $: Sandbox) {
this.handleEstimateChange = $.debounce(this.handleEstimate.bind(this), (1000*0.2));
}
handleEstimate(item: any, estimate: number, input: HTMLInputElement, form: NgForm) {
if (!estimate) this.resetFormControl(input, form);
(this, item, estimate, input, form);
// Why does form.dirty never change back to pristine again???
}
}
注意强>
[attr.name]="..."
(template.html)resetFormControl
基本上,仅仅delete
值是不够的,因为它仍然存在于FormControl
对象(form.controls
)上。要正确清除它,请为单个控件调用control.reset()
- 然后调用.markAsPristine()
与父NgForm
进行通信。此外,input.name
为空,因为它仅由ng-reflect-name
表示,除非[attr.name]
阐明相同的值 - [name]
实际上只是因为它是Angular所需的。
现在,只要<input />
值发生变化 - 和就会失败 - 我们重置输入,确保如果 all 都是假的,Angular会自动处理正确地NgForm
的脏状态。