0

确定 NgForm 看起来是否与任何用户输入之前完全一样


似乎form.dirty在更改后不会对其值进行编辑,并且form.touched似乎总是false无论如何:dirtyistouchedtouchedis tetched

模板.html
<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>
组件.ts
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???
    }

}

在 TypeScript 中,我对处理程序进行去抖动ngModelChange处理,以便 Angular 有机会form.dirty在我检查它之前更改值。这是因为在对象被修改ngModelChange之前被触发。NgForm

如果!estimate, 因为estimate === "", 则将其设置回其原始值undefined。在这种情况下,表单应该看起来与任何用户输入发生之前完全一样。

但是,当我在注释正上方的行上放置一个断点并输出form.dirty到 时consoleNgForm 永远不会变dirtyfalse.

是否可以确定表单看起来是否与任何用户输入之前完全一样?

显然,我可以编写自己的逻辑,但这是否意味着那NgForm是无用的?一定有什么我想念的,对吧?肮脏怎么可能不意味着肮脏

我已经查看了其他一些 SO 问题——第一个类似但绝对不是我要问的问题。他们在问这是否是故意的——我不在乎;我想知道如何实现上述目标。

关闭,但没有雪茄:

即使设置为原始值,angular2 formcontrol 也会保持肮脏

如果表单脏了,则阻止路由[Angular 2]

Angular 2 仅获取控制组中的脏值

如何以编程方式将 Angular 2 表单控件设置为脏?

Angular 2.x/4.x & bootstrap:patchValue 不会改变脏标志。可能的错误?

4

2 回答 2

2

使用模板驱动的表单和一个非常扁平的数据模型,我是这样实现的:

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);
}

但这仅适用于非常简单的情况。

正如我在评论中提到的,使用响应式表单可以让您更灵活地管理与用户条目分开的数据模型。

于 2017-09-05T18:35:55.017 回答
0

什么是最有用的


模板.html
<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>
组件.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]="..."(模板.html)
  • resetFormControl

基本上,仅仅deleteing 值是不够的,因为它仍然存在于FormControl对象 ( form.controls) 上。要正确清除它,control.reset()请为单个控件调用 - 这反过来调用.markAsPristine()与 parent 通信的NgForm。此外,input.name它是空的,因为它仅由ng-reflect-name除非[attr.name]阐明相同的值表示——[name]实际上就在那里,因为它是 Angular 所要求的。

现在,每当一个<input />值发生变化——以及它的错误——我们重置输入以确保如果所有都是错误的,Angular 将自动正确处理NgForm的脏状态。

于 2017-09-05T22:34:42.970 回答