以角反应形式提交表格后显示错误

时间:2019-06-23 11:29:19

标签: angular

我已经创建了一个反应形式,并使用了角材料形式控制。

在表单提交时,我正在调用API,并且该API返回错误,因为其中的formControl值无效

例如Website already registered

现在,我想在中显示此错误消息,但该错误未显示。

  <mat-form-field class="full-width website"
    [appearance]="matAppearance">
    <mat-label>Website URL</mat-label>
    <input matInput
      placeholder="Website URL"
      name="website"
      formControlName="website">
    <mat-error *ngIf="configurationForm.get('website').hasError('required')">
      <strong>(required)</strong>
    </mat-error>
    <mat-error *ngIf="configurationForm.get('website').hasError('pattern')">
      Invalid URL
    </mat-error>
    <mat-error *ngIf="websiteErrMsg">{{websiteErrMsg}}</mat-error>
  </mat-form-field>

  public submitForm() {
      this.testService.register().subscribe(
        sucRes => {
          console.log('done);
        },
        errRes => {
          if (errRes.error === 'Website is already registered') {
              this.websiteErrMsg = 'Website Already Registered!';
          }
        }
      );
  }

问题1 :我在做什么错误?

编辑: 我尝试更改mat-errordiv,然后可以正常工作。现在想知道为什么它不能与mat-error

一起使用

1 个答案:

答案 0 :(得分:1)

这并不确切,但是我认为使用异步验证器(请参阅docs)可以解决您的问题。 asyncValidatros的问题是性能。如果您不使用updateOn'blur'或'submit',则每次更改表单时Angular都会进行呼叫。

想象一下,您有一个服务返回的可观察值是true或false

@Injectable({ providedIn: 'root' })
export class ApiService {
  getWebName(webName: string): Observable<boolean> {
    const isTaken = webName=="Vivek Kumar";
    return of(isTaken).pipe(delay(1000));
  }
}

您需要使用FormGroup和FormControl的构造函数创建formGroup,以指示何时进行评估。无法使用FormBuilder

this.testForm = new FormGroup(
  {
    name: new FormControl("Vivek Kumar", {
      asyncValidators: this.checkIfNotRegister(),
      validators: Validators.required, 
      updateOn: 'blur'
    }),
    age: new FormControl(30, {
       validators:Validators.required,
       updateOn: 'blur'
    })
  }
);

我们的函数“ checkIfNotRegister”是

checkIfNotRegister(): AsyncValidatorFn {
    return (control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
      return this.service.getWebName(control.value).pipe(
        map(res => res ? { repeat: "name yet register" } : null)
      )
    };
  }

.html就像

<form [formGroup]="testForm">
    <mat-form-field class="name" appearance="outline">
        <input matInput placeholder="Name" formControlName="name">
    <mat-error *ngIf="testForm.get('name').hasError('required')">
      Name is required*
    </mat-error>
    <mat-error *ngIf="testForm.get('name').hasError('repeat')">
      Unknown server Error
    </mat-error>
    <mat-hint *ngIf="testForm.get('name').pending">Validating...</mat-hint>
  </mat-form-field>

  <mat-form-field class="age" appearance="outline">
        <input matInput placeholder="Age" formControlName="age">
    <mat-error *ngIf="testForm.get('age').hasError('required')">
      Age is required*
    </mat-error>
  </mat-form-field>

  <div>
    <button type="submit" (click)="submitForm()">Submit</button>
  </div>
</form>

看看我们如何使用<mat-hint>来显示何时检查可观察物

更新仅检查submit()中的异步验证器

如果我们提交以下内容:

  submitForm() {
    if (this.testForm.valid)
    {
      //Add an async validators
      this.testForm.get('name').setAsyncValidators(this.checkIfNotRegister());
      //force Angular to updateValueAndValidity
      this.testForm.get('name').updateValueAndValidity();
      //remove the async validator
      this.testForm.get('name').setAsyncValidators(null);
    }
  }

更新2019-06-27

但是这不等着检查是否有效,因此需要再做一步,以至于怀疑this.testForm.statusChanges,所以我们的SubmitForm变得像

submitForm() {
    if (this.testForm.valid) {
      this.testForm.statusChanges.pipe(take(2),last()).subscribe(res=>{
          //if res=='VALID' make something
          //if res=='INVALID'we don't need make nothing
          console.log(res)
      })
      this.testForm.get('name').setAsyncValidators(this.checkIfNotRegister());
      this.testForm.get('name').updateValueAndValidity({onlySelf:false,emitEvent:true});
      this.testForm.get('name').setAsyncValidators(null);
    }

我们的表单不需要验证器onBlur或onSubmit

this.testForm = new FormGroup(
      {
        name: new FormControl("Vivek Kumar", Validators.required),
        age: new FormControl(30, Validators.required)
      }
    );

您可以在stackblitz中看到最终结果