如何在Angular中获取模板中的表单控件验证错误

时间:2017-07-09 15:43:00

标签: angular angular2-forms angular-reactive-forms

我有一个表单根据下拉列表中的某些值更改其验证。如果选择大学A,则需要最低百分比60,如果选择大学B,则最小百分比降至55。 虽然我已经找到了一种方法来获取模板中的最小错误,这样我就不必在模板中硬编码百分比值。虽然我不确定这是否正确。

<div formGroupName="marks">
  <div class="form-group">
    <label for="email" class="col-lg-3 control-label">Semester 1</label>
    <div class="col-lg-3">
      <input autocomplete="off"
             #sem1
             type="text"
             min="0"
             max="99"
             maxlength="1"
             maxlength="2"
             class="form-control"
             id="email"
             placeholder="Sem 1 (%)"
             (keypress)="onlyNumberKey($event)"
             formControlName="sem1">
      <span *ngIf="registrationForm.controls['marks'].controls['sem1'].hasError('required') &&
                   registrationForm.controls['marks'].controls['sem1'].touched"
                   class="text-danger">
        Sem 1 percentage required
      </span>
      <span *ngIf="registrationForm.controls['marks'].controls['sem1'].hasError('min') ||
                   registrationForm.controls['marks'].controls['sem1'].hasError('max') ||
                   registrationForm.controls['marks'].controls['sem1'].hasError('minlength')||
                   registrationForm.controls['marks'].controls['sem1'].hasError('maxlength') &&
                   registrationForm.controls['marks'].controls['sem1'].touched"
                   class="text-danger">
        Percenatge must be {{ registrationForm.get('marks.sem1')._errors.min.min }}  and above.
      </span>
    </div>
  </div>
</div>

组件

registrationForm = new FormGroup({
  college: new FormControl('', [
    Validators.required, dropDrownValidator
  ]),
  marks: new FormGroup({
    sem1: new FormControl('',
      [
        Validators.required,
        Validators.min(60),
        Validators.max(99),
        Validators.minLength(1),
        Validators.maxLength(2)
      ]
    )
  })
});

1 个答案:

答案 0 :(得分:0)

嗯,值得一提的是minmax内置验证器由于4.3.0-beta.0而在this issue中回滚,不再导出(可能)在4.3.0 最终中。可能他们应该回到v5。

话虽如此,我建议您使用自己的自定义验证程序或从源代码中复制min 验证程序({{1 }})到你的项目,以防止将来休息。

以下是修改后的复制粘贴版本:

@angular/forms

要实现您的目标,您必须观看 function customMin(min: number): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { if (control.value == null || min == null) { return null; } const value = parseFloat(control.value); return isNaN(value) || value >= min ? null : { customMin: { min, actual: control.value } }; }; } 控件中的更改。

您可以使用模板

中的college执行此操作
(change)

甚至在组件中使用<select formControlName="college" (change)="myAwesomeFunction($event.target.value)"> ... </select>

valueChanges

在您的this.registrationForm.get('college').valueChanges.subscribe(college => this.myAwesomeFunction(college)); 中,根据大学用户选择的内容,您可以使用AbstractControl#setValidators为您的验证码设置最小值,如下所示:

function

<强>提示:

1 - 因为,您使用的是模型驱动的表单,所以不应该在HTML中放置验证,保持清洁并将所有内容放在组件中。

2 - 您可以使用myAwesomeFunction() { const min: number = college === 'CollegeA' ? 60 : 55; const control: FormControl = this.registrationForm.get('marks.sem1'); control.setValidators([Validators.required, customMin(min)]); control.updateValueAndValidity(); } 来简化FormBuilder的构建(请参阅下面的PLUNKER)。

3 - 你永远不应该访问这样的私有财产:

form

如果需要,只需使用{{ registrationForm.get('marks.sem1')._errors.min.min 代替errors

4 - 您可以简化更多标记:

而不是:

_errors

你可以:

<span *ngIf="registrationForm.controls['marks'].controls['sem1'].hasError('required') &&
             registrationForm.controls['marks'].controls['sem1'].touched" 
             class="text-danger">
  Sem 1 percentage required
</span>
<span *ngIf="registrationForm.controls['marks'].controls['sem1'].hasError('min') ||
             registrationForm.controls['marks'].controls['sem1'].hasError('max') ||
             registrationForm.controls['marks'].controls['sem1'].hasError('minlength')||
             registrationForm.controls['marks'].controls['sem1'].hasError('maxlength') &&
             registrationForm.controls['marks'].controls['sem1'].touched"
             class="text-danger">
  Percenatge must be {{ registrationForm.get('marks.sem1')._errors.min.min }}  and above.
</span>

WORKING DEMO (using custom validator)

PS:如果您不关心将来版本中的中断,但仍想使用<div class="text-danger" *ngIf="registrationForm.get('marks.sem1').touched"> <span *ngIf="registrationForm.hasError('required', 'marks.sem1')"> Sem 1 percentage required </span> <span *ngIf="registrationForm.getError('customMin', 'marks.sem1') as error"> Percentage must be greater than or equal to {{ error.min }}. </span> </div> ,则只需更改此行:

Validators.min

到此:

control.setValidators([Validators.required, customMin(min)]);

WORKING DEMO (using built-in validator)