Angular FormControl 值的变化会触发 formgroup 中的每一次变化
Angular FormControl value changes triggers every change in formgroup
我正在尝试进行 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
我希望仅当电子邮件输入更改时才触发值更改。
提前致谢!
您可以为此使用 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 调用,在最后一次更改后几秒钟。
你可以看到 .
为此您需要订阅电子邮件控件的 valueChange
,而不是整个表单。
可能是这样的:
this.form01.get("email").valueChanges
.subscribe((emailValue: string) => {
// you have email value here
});
但是
反应式表单有一个异步验证器选项。我认为它更适合这种情况。这样 Angular 将为您处理所有错误和表单状态。
另外一个提示,添加一个带有一些延迟的 debounceTime()
管道,这样它就不会在每次击键时发送请求。这样你就可以节省你的后端。
文档:https://angular.io/guide/form-validation#creating-asynchronous-validators
我正在尝试进行 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
我希望仅当电子邮件输入更改时才触发值更改。 提前致谢!
您可以为此使用 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 调用,在最后一次更改后几秒钟。
你可以看到
为此您需要订阅电子邮件控件的 valueChange
,而不是整个表单。
可能是这样的:
this.form01.get("email").valueChanges
.subscribe((emailValue: string) => {
// you have email value here
});
但是
反应式表单有一个异步验证器选项。我认为它更适合这种情况。这样 Angular 将为您处理所有错误和表单状态。
另外一个提示,添加一个带有一些延迟的 debounceTime()
管道,这样它就不会在每次击键时发送请求。这样你就可以节省你的后端。
文档:https://angular.io/guide/form-validation#creating-asynchronous-validators