我正在尝试验证数据库中是否存在一个名字。如果存在,我想把它标记为无效,并通知用户这个情况。
除此以外,我正在寻找最好的方法来完成这个任务:模板驱动的表单或反应式表单。
请注意,我使用的是多个表单,就像下面的例子一样。https:/material.angular.io。.
这是我目前的代码。
HTML:
<mat-horizontal-stepper [@.disabled]="true" #stepper>
<mat-step label="Example" [stepControl]="nameForm">
<form [formGroup]="nameForm">
<mat-form-field>
<mat-label>NAME</mat-label>
<input matInput placeholder="Input name" formControlName="name">
</mat-form-field>
<button
matTooltip="Verify name in data base"
(click)="validateName()" <<<< LOOK, HERE IS THE POINT
[disabled]="!loading">Validate Name
<i class="ml-2 fa fa-refresh fa-spin" *ngIf="!loading"></i>
</button>
<div>
<button mat-button matStepperNext>Next</button>
</div>
</form>
</mat-step>
<mat-step label="Endereço" [stepControl]="enderecoForm">
<form [formGroup]="nameForm2">
<mat-form-field>
...
</mat-form-field>
</form>
</mat-step>
... more steps with one form inside of each one
TS:
export class SomeComponent {
constructor(private readonly _formBuilder: FormBuilder) {}
ngOnInit(): void {
this.nameForm = this._formBuilder.group(
{
name: ['', Validators.required],
},
{ validator: this.validateName },
); // AND HERE LOOK
this.nameForm2 = this._formBuilder.group({
name2: ['', Validators.required],
// ... more forms and controls validators with reactive forms
});
}
validateName(fb: FormGroup) {
const nameCtrl = fb.get('name');
// method verifyName return the name from database if exists
const name = this.nameService.verifyName(nameCtrl);
if (nameCtrl.errors == null || 'exists' in nameCtrl.errors) {
if (name == null) {
nameCtrl.setErrors(null);
} else {
nameCtrl.setErrors({ exists: true });
}
}
}
}
我不太明白,如果你想用以下方法来验证 AsyncValidator
或点击按钮后,但我们在这里。
asyncValidators
:import { Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { Observable, of as just } from 'rxjs';
import { catchError } from 'rxjs/operators';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'app-some',
templateUrl: './some-component.html'
})
export class SomeComponent {
readonly formGroup = this.formBuilder.group(
{
name: ['', Validators.required, this.validateName]
},
{ updateOn: 'blur' }
);
constructor(private readonly formBuilder: FormBuilder) {}
// For this case, I'd suggest you to name it something like `nameAsyncValidator`.
// In any case it's up to you :)
private validateName(): Observable<{ exists: boolean } | null> {
const { errors, value } = this.formGroup.get('name')!;
if (errors || !value) return just(null);
return this.nameService.verifyName(value).pipe(
catchError(() => just(null))
);
}
}
this.validateName
作为第3个参数,哪一个是特定的?asyncValidators
.{ updateOn: 'blur' }
以防止向服务器发出不必要的请求。这些请求将只在模糊时发出。import { ChangeDetectionStrategy, Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { catchError, take, tap } from 'rxjs/operators';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'app-some',
templateUrl: './some-component.html'
})
export class SomeComponent {
readonly formGroup = this.formBuilder.group({
name: ['', Validators.required]
});
validateName(): void {
const nameFormControl = this.formGroup.get('name')!;
const { errors, value } = nameFormControl;
if (errors || !value) return;
return this.nameService.verifyName(value).pipe(
take(1),
catchError(() => just(null)),
tap(exists => nameFormControl.setErrors(exists))
)
.subscribe();
}
}
请注意,由于你没有包括签名的。nameServive.verifyName
在问题中,我假设它返回 Observable<{ exists: boolean } | null>
.