我已经创建了一个反应形式,并使用了角材料形式控制。
在表单提交时,我正在调用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-error
或div
,然后可以正常工作。现在想知道为什么它不能与mat-error
答案 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中看到最终结果