angular 8 中未以反应形式显示表单验证错误消息
Form Validation Error Message Not Showing in reactive forms in angular 8
为什么不显示此表单控件错误消息
我有一个数组,正在读取它并动态生成问题。
我找不到我在这段代码中犯了什么错误。
我必须显示 4 条错误消息
- 必填
- 最小值验证
- 最大值验证
- 唯一值验证
我有一个包含问题的数组
questions: any = [{
id: 13,
surveyNo: 5,
qNo: 3,
question: 'Please rank the following features in order of importance,where 1 is the most important to you.?',
qType: 3,
noAnswrs: 4,
answerType: 1,
answers: ['Location', 'Confort', 'Service', 'Value for money']
}];
我同样动态生成了表单控制器,
createForms(): any {
this.surveyQuestionForm = this.fb.group(
this.questions.reduce((group: any, question: { qNo: string; }) => {
return Object.assign(group, { ['q' + question.qNo]: this.buildSubGroup(question) });
}, {})
);
}
private buildSubGroup(question) {
switch (question.qType) {
case 3:
return this.fb.group(
question.answers.reduce((subGroup, answer) => {
return Object.assign(subGroup, { [answer]: ['', [Validators.required, Validators.min(1), Validators.max(3)]] });
}, {}), { validators: [this.uniqueNumbersValidator()] }
);
default:
throw new Error('unhandled question type');
}
}
uniqueNumbersValidator() {
return (ctrl: AbstractControl) => {
const fg = ctrl as FormGroup;
let allUnique = true;
const values = [];
Object.values(fg.controls).forEach(fc => {
const val = fc.value;
if (val && allUnique) {
if (values.includes(val) && allUnique) {
allUnique = false;
}
values.push(val);
}
});
return (allUnique) ? null : { notAllUnique: true };
};
}
这是我的 html 代码
<div class="form-group" formGroupName="{{'q' + question.qNo}}">
<label class="control-label"> {{question.qNo}})
{{question.question}}</label>
<div class="ml-3">
<table>
<tr *ngFor="let anwr of question.answers; let a=index">
<td>{{a+1}}. {{anwr}} </td>
<div class="invalid-feedback"
*ngIf="surveyQuestionForm.get('q'+ question.qNo).touched
&& surveyQuestionForm.get('q'+ question.qNo).hasError('required')">
Answer required</div>
<div class="invalid-feedback"
*ngIf="surveyQuestionForm.get('q'+ question.qNo).touched
&& surveyQuestionForm.get('q'+ question.qNo).hasError('max')">
max value</div>
<div class="invalid-feedback"
*ngIf="surveyQuestionForm.get('q'+ question.qNo).touched
&& surveyQuestionForm.get('q'+ question.qNo).hasError('min')">
min value</div>
<div class="invalid-feedback"
*ngIf="surveyQuestionForm.get('q'+ question.qNo).touched
&& surveyQuestionForm.get('q'+ question.qNo).hasError('notAllUnique')">
Already inserted value</div>
<td>
<input type="number" style="width:40px;" id="q{{question.qNo}}_{{a}}"
[ngClass]="{'is-invalid': surveyQuestionForm.get('q'+ question.qNo).errors
&& surveyQuestionForm.get('q'+ question.qNo).touched}" formControlName="{{anwr}}" class="text-center" />
</td>
</tr>
</table>
</div>
</div>
这是 stackblitz 代码
https://stackblitz.com/edit/angular-pxdesk
请告诉我这是什么问题。
谢谢
这里的问题是您没有区分出错的组还是出错的控件。
您需要确保在验证器不在控件上时在控件上访问错误,在验证器在组上时在组上访问错误,因此您需要这样做:
<div class="invalid-feedback"
*ngIf="surveyQuestionForm.get('q'+ question.qNo).get(anwr).touched && surveyQuestionForm.get('q'+ question.qNo).get(anwr).hasError('required')">
Answer required</div>
<div class="invalid-feedback"
*ngIf="surveyQuestionForm.get('q'+ question.qNo).get(anwr).touched && surveyQuestionForm.get('q'+ question.qNo).get(anwr).hasError('max')">
max value</div>
<div class="invalid-feedback"
*ngIf="surveyQuestionForm.get('q'+ question.qNo).get(anwr).touched && surveyQuestionForm.get('q'+ question.qNo).get(anwr).hasError('min')">
min value</div>
控制级别错误。如果您不确保检查控件是否也被触摸,那么错误将出现在错误的时间。
对于组级错误,您可能希望将其移出各个控件,并与组一起显示,因为它是组级错误。在您当前的方案中,如果您有重复值,则错误将出现在每个触摸的控件旁边。所以改为这样做...
<div class="invalid-feedback"
*ngIf="surveyQuestionForm.get('q'+ question.qNo).touched && surveyQuestionForm.get('q'+ question.qNo).hasError('notAllUnique')">
Already inserted value</div>
你的 ngFor 之外的答案。请注意,我们正在访问该组,因为这是一个组级错误。
旁注:您可能希望最大验证器为 4 而不是 3,因为您需要 4 个不同的数字。
这里是固定闪电战:https://stackblitz.com/edit/angular-hbtvnc?file=src/app/app.component.html
为什么不显示此表单控件错误消息 我有一个数组,正在读取它并动态生成问题。 我找不到我在这段代码中犯了什么错误。
我必须显示 4 条错误消息
- 必填
- 最小值验证
- 最大值验证
- 唯一值验证
我有一个包含问题的数组
questions: any = [{
id: 13,
surveyNo: 5,
qNo: 3,
question: 'Please rank the following features in order of importance,where 1 is the most important to you.?',
qType: 3,
noAnswrs: 4,
answerType: 1,
answers: ['Location', 'Confort', 'Service', 'Value for money']
}];
我同样动态生成了表单控制器,
createForms(): any {
this.surveyQuestionForm = this.fb.group(
this.questions.reduce((group: any, question: { qNo: string; }) => {
return Object.assign(group, { ['q' + question.qNo]: this.buildSubGroup(question) });
}, {})
);
}
private buildSubGroup(question) {
switch (question.qType) {
case 3:
return this.fb.group(
question.answers.reduce((subGroup, answer) => {
return Object.assign(subGroup, { [answer]: ['', [Validators.required, Validators.min(1), Validators.max(3)]] });
}, {}), { validators: [this.uniqueNumbersValidator()] }
);
default:
throw new Error('unhandled question type');
}
}
uniqueNumbersValidator() {
return (ctrl: AbstractControl) => {
const fg = ctrl as FormGroup;
let allUnique = true;
const values = [];
Object.values(fg.controls).forEach(fc => {
const val = fc.value;
if (val && allUnique) {
if (values.includes(val) && allUnique) {
allUnique = false;
}
values.push(val);
}
});
return (allUnique) ? null : { notAllUnique: true };
};
}
这是我的 html 代码
<div class="form-group" formGroupName="{{'q' + question.qNo}}">
<label class="control-label"> {{question.qNo}})
{{question.question}}</label>
<div class="ml-3">
<table>
<tr *ngFor="let anwr of question.answers; let a=index">
<td>{{a+1}}. {{anwr}} </td>
<div class="invalid-feedback"
*ngIf="surveyQuestionForm.get('q'+ question.qNo).touched
&& surveyQuestionForm.get('q'+ question.qNo).hasError('required')">
Answer required</div>
<div class="invalid-feedback"
*ngIf="surveyQuestionForm.get('q'+ question.qNo).touched
&& surveyQuestionForm.get('q'+ question.qNo).hasError('max')">
max value</div>
<div class="invalid-feedback"
*ngIf="surveyQuestionForm.get('q'+ question.qNo).touched
&& surveyQuestionForm.get('q'+ question.qNo).hasError('min')">
min value</div>
<div class="invalid-feedback"
*ngIf="surveyQuestionForm.get('q'+ question.qNo).touched
&& surveyQuestionForm.get('q'+ question.qNo).hasError('notAllUnique')">
Already inserted value</div>
<td>
<input type="number" style="width:40px;" id="q{{question.qNo}}_{{a}}"
[ngClass]="{'is-invalid': surveyQuestionForm.get('q'+ question.qNo).errors
&& surveyQuestionForm.get('q'+ question.qNo).touched}" formControlName="{{anwr}}" class="text-center" />
</td>
</tr>
</table>
</div>
</div>
这是 stackblitz 代码 https://stackblitz.com/edit/angular-pxdesk
请告诉我这是什么问题。
谢谢
这里的问题是您没有区分出错的组还是出错的控件。
您需要确保在验证器不在控件上时在控件上访问错误,在验证器在组上时在组上访问错误,因此您需要这样做:
<div class="invalid-feedback"
*ngIf="surveyQuestionForm.get('q'+ question.qNo).get(anwr).touched && surveyQuestionForm.get('q'+ question.qNo).get(anwr).hasError('required')">
Answer required</div>
<div class="invalid-feedback"
*ngIf="surveyQuestionForm.get('q'+ question.qNo).get(anwr).touched && surveyQuestionForm.get('q'+ question.qNo).get(anwr).hasError('max')">
max value</div>
<div class="invalid-feedback"
*ngIf="surveyQuestionForm.get('q'+ question.qNo).get(anwr).touched && surveyQuestionForm.get('q'+ question.qNo).get(anwr).hasError('min')">
min value</div>
控制级别错误。如果您不确保检查控件是否也被触摸,那么错误将出现在错误的时间。
对于组级错误,您可能希望将其移出各个控件,并与组一起显示,因为它是组级错误。在您当前的方案中,如果您有重复值,则错误将出现在每个触摸的控件旁边。所以改为这样做...
<div class="invalid-feedback"
*ngIf="surveyQuestionForm.get('q'+ question.qNo).touched && surveyQuestionForm.get('q'+ question.qNo).hasError('notAllUnique')">
Already inserted value</div>
你的 ngFor 之外的答案。请注意,我们正在访问该组,因为这是一个组级错误。
旁注:您可能希望最大验证器为 4 而不是 3,因为您需要 4 个不同的数字。
这里是固定闪电战:https://stackblitz.com/edit/angular-hbtvnc?file=src/app/app.component.html