表单验证错误消息未以反应形式显示在角度8中

时间:2019-07-21 06:27:42

标签: typescript angular8

为什么此表单控件错误消息未显示 我有一个数组,正在阅读并动态生成问题。 我找不到在此代码中犯的错误。

我必须显示4条错误消息

  1. 必需
  2. 最小值验证
  3. 最大值验证
  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

请告诉我这是什么问题。

谢谢

1 个答案:

答案 0 :(得分:1)

这里的问题是您无法区分出现错误的组或出现错误的控件。

您需要确保当验证者是控件时,正在访问控件上的错误;当控件在组中时,正在访问组中的错误,因此您需要执行以下操作:

<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