角度6:不要触发验证器setValue

时间:2018-06-25 13:04:23

标签: angular angular-forms

我正在使用Angular 6.

构建CRUD应用程序

我的表单用于添加和更新项目。当用户更新项目时,将从服务器中预先填充表单。服务器更新表单时会触发验证。

如何在不触发验证的情况下更新表单值?

以下是相关代码:

ngOnInit(){
    this.form = this.fb.group({
        name: ['', [Validators.required], MyAsyncValidator],
        comments: [''],
    });

    this.http.get('/api')
        .subscribe((data: any) => {
            this.form.setValue({ name: data.name, comments: data.comments });
        });
    //How to populate form without triggering validation
}

模板:

<form [formGroup]="form">
<div class="form-group row">
    <label class="col-sm-2 col-form-label">Name</label>
    <div class="col-sm-10">
        <input formControlName="name"
            class="form-control"
            [ngClass]="{'is-invalid': isInvalid(form.controls.name)}"
            type="text">
        <small *ngIf="form.get('name').status=='PENDING'" class="form-text text-muted">
            <i class="fa fa-spinner fa-spin"></i> Checking Name...
        </small>
        <small class="invalid-feedback">
            <div *ngIf="form.controls['name'].hasError('required')">Name Required</div>
            <div *ngIf="form.controls['name'].hasError('exists')">Name Exists</div>
        </small>
    </div>
</div>

4 个答案:

答案 0 :(得分:1)

我认为这要么是角度错误,要么是代码中实现的一些怪异行为。我遇到了同样的问题,并通过源代码进行了调试,才发现了这一点:

setValue将调用updateValueAndValidity():https://github.com/angular/angular/blob/39c8baea318e740111b1c748718c3203a61b4cdf/packages/forms/src/model.ts#L941

并在updateValueAndValidity()中调用asyncValidatior: https://github.com/angular/angular/blob/39c8baea318e740111b1c748718c3203a61b4cdf/packages/forms/src/model.ts#L554

我的印象是,在设置emitEvent: false时,不应触发任何验证,但是事实并非如此。甚至更奇怪的是,无论您将updateOn设置为change还是blur,asyncValidator都会在setValue上触发。

我别无选择,只能在每次setValue调用之前删除asyncValidator,然后再添加回去。

答案 1 :(得分:0)

尝试单独更新它们。

this.form.controls.name.setValue(data.name);
this.form.controls.comments.setValue(data.comments);

在HTML中将此用于异步验证器:

<small class="invalid-feedback">
    <div *ngIf="form.controls['name'].hasError('required')">Name Required</div>
    <div *ngIf="form.controls['name'].touched && form.controls['name'].hasError('exists')">Name Exists</div>
</small>

答案 2 :(得分:0)

您为什么要setValue

我建议您在收到响应时绑定值。如果响应为null或为空,则为空白,否则将填充值。

代码:

ngOnInit(){
  this.http.get('/api')
    .subscribe((data: any) => {
       this.form = this.fb.group({
             name: [data.name || '', [Validators.required], MyAsyncValidator],
             comments: [data.comments || ''],
        });
    });
}

答案 3 :(得分:0)

遇到同样的问题。

在致电control.markAsTouched()之前先致电control.setValue(value)可以解决我的情况。

这是否意味着仅在触摸控件时验证才会失败?嗯...

我正在使用Angular 7 btw