为什么表单错误的 getter 在我的 Angular Reactive Form 组件模板中不起作用,但直接引用却起作用?
Why don't getters for form errors work in my Angular Reactive Form component template, but a direct reference does?
快速提问。这是那些烦人的小错误之一。我在延迟加载的注册模块中有一个 Angular 反应形式。代码结构如下:
TS
get email() {
return this.myForm.get('email');
}
// This code works from within the component, but not when referenced from within the template.
HTML
<div class="errors" *ngIf="email.errors?.required && email.touched">Must enter email</div>
在模板中,div 永远不会显示,因为表达式永远不会计算为真,即使出现错误也是如此。我已经在控制台中查看了。
更令人困惑的是,我在 component.ts
中使用 getter 没有问题,事实上,我 console.log
的方式是写 console.log(this.email.errors)
.这很好用。但不在模板中。
我的混乱解决方案是直接访问错误,确实有效:
<div class="errors" *ngIf="myForm.controls.email.errors.required && myForm.controls.email.touched">
Must enter email
</div>
// This works! As you can see the expression is very long and messy.
感谢任何帮助!
为了使用响应式表单,请确保您在模板中使用 formGroup
和 formControlName
指令,如下所示:
<form (ngSubmit)="submit()" [formGroup]="myForm">
<label for="username">Username</label>
<input type="text" id="username" formControlName="username">
<span *ngIf="username.getError('required') &&
(username.dirty || username.touched)">
Username is required
</span>
<label for="password">Password</label>
<input type="password" id="password" formControlName="password">
<span *ngIf="myForm.get('password').getError('required') &&
(myForm.get('password').dirty || myForm.get('password').touched)">
Password is required
</span>
<input type="submit" value="Submit">
</form>
然后定义您的 FormGroup
实例、验证器和 getter 函数:
myForm: FormGroup = new FormGroup({
username: new FormControl('', Validators.required),
password: new FormControl('', Validators.required),
});
get username() {
return this.myForm.get('username');
}
get password() {
return this.myForm.get('password');
}
之后,您可以使用getter函数进行验证(作为模板中的用户名)或使用直接引用myForm.get('password').getError('required')
(作为模板中的密码)。
在此处查看 Angular 中应用两种方式访问反应式表单错误的登录示例:https://stackblitz.com/edit/reactive-forms-get-errors
如果有帮助请告诉我!
您有没有在输入字段中使用模板引用变量 #email
,例如:<input #email ...>
?
这样就可以说明问题了。我做了一个重现错误的 Stackblitz:https://stackblitz.com/edit/angular-qyt7kb
在该示例中,firstName 输入具有模板引用变量#firstName 并且从未显示错误 div。姓氏错误 div 显示正确。
<form [formGroup]="form">
<label>
First Name:
<input #firstName type="text" formControlName="firstName">
</label>
<div *ngIf="firstName.errors?.required && firstName.touched">*FIRST Name is Required</div>
<label>
Last Name:
<input type="text" formControlName="lastName">
</label>
<div *ngIf="lastName.errors?.required && lastName.touched">*LAST name is Required</div>
</form>
所以看起来在模板中,模板引用变量优先于TS文件中同名的getter。在示例中,您可以看到 console.log 正确打印了错误,就像您所说的那样。
快速提问。这是那些烦人的小错误之一。我在延迟加载的注册模块中有一个 Angular 反应形式。代码结构如下:
TS
get email() {
return this.myForm.get('email');
}
// This code works from within the component, but not when referenced from within the template.
HTML
<div class="errors" *ngIf="email.errors?.required && email.touched">Must enter email</div>
在模板中,div 永远不会显示,因为表达式永远不会计算为真,即使出现错误也是如此。我已经在控制台中查看了。
更令人困惑的是,我在 component.ts
中使用 getter 没有问题,事实上,我 console.log
的方式是写 console.log(this.email.errors)
.这很好用。但不在模板中。
我的混乱解决方案是直接访问错误,确实有效:
<div class="errors" *ngIf="myForm.controls.email.errors.required && myForm.controls.email.touched">
Must enter email
</div>
// This works! As you can see the expression is very long and messy.
感谢任何帮助!
为了使用响应式表单,请确保您在模板中使用 formGroup
和 formControlName
指令,如下所示:
<form (ngSubmit)="submit()" [formGroup]="myForm">
<label for="username">Username</label>
<input type="text" id="username" formControlName="username">
<span *ngIf="username.getError('required') &&
(username.dirty || username.touched)">
Username is required
</span>
<label for="password">Password</label>
<input type="password" id="password" formControlName="password">
<span *ngIf="myForm.get('password').getError('required') &&
(myForm.get('password').dirty || myForm.get('password').touched)">
Password is required
</span>
<input type="submit" value="Submit">
</form>
然后定义您的 FormGroup
实例、验证器和 getter 函数:
myForm: FormGroup = new FormGroup({
username: new FormControl('', Validators.required),
password: new FormControl('', Validators.required),
});
get username() {
return this.myForm.get('username');
}
get password() {
return this.myForm.get('password');
}
之后,您可以使用getter函数进行验证(作为模板中的用户名)或使用直接引用myForm.get('password').getError('required')
(作为模板中的密码)。
在此处查看 Angular 中应用两种方式访问反应式表单错误的登录示例:https://stackblitz.com/edit/reactive-forms-get-errors
如果有帮助请告诉我!
您有没有在输入字段中使用模板引用变量 #email
,例如:<input #email ...>
?
这样就可以说明问题了。我做了一个重现错误的 Stackblitz:https://stackblitz.com/edit/angular-qyt7kb
在该示例中,firstName 输入具有模板引用变量#firstName 并且从未显示错误 div。姓氏错误 div 显示正确。
<form [formGroup]="form">
<label>
First Name:
<input #firstName type="text" formControlName="firstName">
</label>
<div *ngIf="firstName.errors?.required && firstName.touched">*FIRST Name is Required</div>
<label>
Last Name:
<input type="text" formControlName="lastName">
</label>
<div *ngIf="lastName.errors?.required && lastName.touched">*LAST name is Required</div>
</form>
所以看起来在模板中,模板引用变量优先于TS文件中同名的getter。在示例中,您可以看到 console.log 正确打印了错误,就像您所说的那样。