Angular FormControl值的更改会触发表单组中的每一次更改



我试图进行一个api调用来检查用户电子邮件的唯一性,但问题是值的更改会触发所有表单控件中的每一次更改。

这是我的代码:

Errors(){
this.form01.valueChanges
.subscribe((changedObj: any) => {
this.valid = this.form01.valid;
// Checks wether the email exists or not
if (this.form01.get("email").valueChanges) {
console.log("value of email changed");
}
});
}

我的表单组:

// Form Group And It's Form Controls
form01 = new FormGroup({
firstName: new FormControl('', [Validators.required]),
lastName: new FormControl('', [Validators.required]),
email: new FormControl('', [Validators.required, Validators.email]),
phone: new FormControl('', [Validators.required]),
password: new FormControl('', [Validators.required]),
roleID: new FormControl('', [Validators.required]),
});

我的输入:

<form #addCityForm="ngForm" (ngSubmit)="create()" [formGroup]="form01">
<div mat-dialog-content>
<!-- First Name -->
<p>
<mat-form-field appearance="legacy">
<mat-label>First Name</mat-label>
<input matInput name="firstName" formControlName="firstName" [(ngModel)]="model.firstName" placeholder="First Name">
<mat-error *ngIf="!valid">{{getError('firstName')}}</mat-error>
</mat-form-field>
</p>
<!-- Last Name -->
<p>
<mat-form-field appearance="legacy">
<mat-label>Last Name</mat-label>
<input matInput name="lastName" formControlName="lastName" [(ngModel)]="model.lastName" placeholder="Last Name"> 
<mat-error *ngIf="!valid">{{getError('lastName')}}</mat-error>   
</mat-form-field>
</p>
<!-- Email -->
<p>
<mat-form-field appearance="legacy">
<mat-label>Email</mat-label>
<input matInput name="email" formControlName="email" [(ngModel)]="model.email" placeholder="Email">  
<mat-error *ngIf="!valid">{{getError('email')}}</mat-error>          
<mat-hint class="validation-error" *ngIf="emailTaken">This Email is taken</mat-hint>  

</mat-form-field>
</p>
<!-- Phone -->
<p>
<mat-form-field appearance="legacy">
<mat-label>Phone</mat-label>
<input matInput name="phone" formControlName="phone" [(ngModel)]="model.phone" placeholder="Phone">
<mat-error *ngIf="!valid">{{getError('phone')}}</mat-error>
<mat-hint class="validation-error" *ngIf="phoneTaken">This Phone is taken</mat-hint>  
</mat-form-field>
</p>
<!-- Role -->
<p>
<mat-form-field class="example-full-width">
<mat-label>Role</mat-label>
<input name="roleID" type="text" placeholder="Role"
aria-label="Employee" matInput formControlName="roleID" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let role of roles" [value]="role.name" (click)="customRole(role.id)">
{{role.name}}
</mat-option>
</mat-autocomplete>
<mat-error *ngIf="!valid">{{getError('roleID')}}</mat-error>
</mat-form-field>
</p>
<!-- Password -->
<p>
<mat-form-field appearance="legacy">
<mat-label>Password</mat-label>
<input type="password" matInput name="password" formControlName="password" [(ngModel)]="model.password" placeholder="Password">
<mat-error *ngIf="!valid">{{getError('password')}}</mat-error>
</mat-form-field>
</p>
</div>
<div mat-dialog-actions>
<button mat-dialog-close [mat-dialog-close]="model" [disabled]="!valid" mat-button type="submit">Save</button>
<button mat-dialog-close mat-button type="button">Close</button>
</div>

</form>

这是getError函数

// Errors Messages
getError(field: string){
if (this.form01.get(field).hasError('required')) {
return "You must enter a value";
}
if (this.form01.get(field).hasError('email')) {
return "Invalid Mail";
}
}

在firstName或lastName输入中写入时的结果:

value of email changed

我希望只有当电子邮件输入发生更改时才触发值更改。提前谢谢!

为此,您需要订阅电子邮件控件的valueChange,而不是整个表单。

可能是这样的:

this.form01.get("email").valueChanges
.subscribe((emailValue: string) => {
// you have email value here
});

但是

对于反应式表单,可以选择异步验证器。我认为它更适合这种情况。这样Angular将为您处理所有错误和表单状态。

还有一个提示,添加一个具有一定延迟的debounceTime()管道,这样它就不会在每次按键时都发送请求。这样,您就可以省去后端。

文档:https://angular.io/guide/form-validation#creating-异步验证器

您可以使用get((函数:

this.form01.get("email").valueChanges
.subscribe(email => {
console.log(email);
});

另一种方法是手动检查最新值:

lastEmail: string;
Error() {
this.form01.valueChanges
.subscribe(obj => {
if (lastEmail !== obj?.email) {
lastEmail = obj?.email;
console.log(lastEmail);
} 
});
}

PS:您应该考虑,对每个新值调用一个api调用可能会带来问题,因为可能会发生多个api调用。

我建议您在最后一次更改几秒钟后,使用不同的最新值来限制api调用。

你可以看到相对线程。

最新更新