ng-invalid未添加到无效的选择/下拉元素

时间:2017-02-16 23:25:26

标签: angular angular2-forms

我有一个带有输入和选择标签的表单。

当所有标签无效时,它们应显示红色左边框。

仅适用于输入标签,但不适用于选择标签。

无效输入标记在运行时应用了这些css类:

class="form-control ng-pristine ng-invalid ng-touched"

无效 select-tag在运行时应用了这些css类:

class="form-control ng-valid ng-touched ng-dirty"

正如您在屏幕截图中看到的那样,两个下拉菜单/选择元素都没有通过此css添加红色/绿色左边框:

.ng-valid[required], .ng-valid.required  {
  border-left: 5px solid #42A948; /* green */
}

.ng-invalid:not(form)  {
  border-left: 5px solid #a94442; /* red */
}

enter image description here

我应该提一下,select-tags的验证是自定义验证,其错误是从schooylearForm而不是schoolyearForm.bestGrade属性中检索的。也许这就是问题,我仍然需要手动将控制状态设置为无效,将ng-invalid类添加到select-tag ???

HTML

<div class="form-group row">
  <label class="col-xs-3 col-form-label" for="power">Beste Note für einen Test</label>
  <div class="col-xs-3">
    <select formControlName="bestGrade" class="form-control">
        <option *ngFor="let t of allGrades" [ngValue]="t">{{t}}</option>
    </select>
  </div>
  <div class="col-xs-6" *ngIf="schoolyearForm.controls.bestGrade.touched">
    <div class="form-error form-control" *ngIf="schoolyearForm.hasError('equalGrades')">
      Beste Note darf nicht gleich schlechteste Note sein.
    </div>
  </div>
</div>

组件

   this.schoolyearForm = this.formBuilder.group({
      name: [this.createSchoolyear.name, [Validators.minLength(3), Validators.required]],
      endDate: [this.createSchoolyear.endDate, Validators.required],
      startDate: [this.createSchoolyear.startDate, Validators.required],
      bestGrade: [this.createSchoolyear.bestGrade],
      worstGrade: [this.createSchoolyear.worstGrade,]
    },  {validator: matchingGrades('bestGrade', 'worstGrade')});

验证

export function matchingGrades(bestGrade: string, worstGrade: string) {
  return (group: FormGroup): {[key: string]: any} => {
    let bestGradeObject = group.controls[bestGrade];
    let worstGradeObject = group.controls[worstGrade];

    if (bestGradeObject.value == worstGradeObject.value) {

      // bestGradeObject.markAsInvalid = true // DOES NOT EXIST !
      return {
        equalGrades: true
      };
    }
  }
}

更新

当我改变这个css时,我发出了声音:

.ng-invalid:not(form)  {
  border-left: 5px solid #a94442; /* red */
}

.ng-invalid  {
  border-left: 5px solid #a94442; /* red */
}

然后当两个select-tags都选择相同的值时,整个表单确实会获得红色边框。

然后我将我的问题改为:

如何使equalGrade自定义验证取决于bestGrade / worstGrade这两个属性,而不是整体。

更新2

我使用了该代码:

  if (bestGradeObject.value == worstGradeObject.value)
        {
            bestGradeObject.setErrors({ "equalGrades": true });
            worstGradeObject.setErrors({ "equalGrades": true });
            return {
                equalGrades: true
            };
        }
        else 
        {
            bestGradeObject.setErrors(null);
            worstGradeObject.setErrors(null);
        }

更新3

enter image description here

现在我使用了来自用户&#39; developer033&#39;

的代码

使用FormControl级别的Validation而不是FormGroup级别。

最初,由于我不喜欢的水平变化,一个下拉列表没有设置红色边框。

如何解决这个问题?

P.S。它是一个鸡蛋问题,我现在无法将worstGradeCtrl传递给bestGradeCtrl的构造函数...

1 个答案:

答案 0 :(得分:0)

嗯,您正在将验证程序设置为formGroup,因此,您拥有的验证程序正在以它应该的方式运行。

如果您想为特定 formControl 设置错误,您可以执行以下操作:

<强>组件:

this.nameCtrl = new FormControl(this.createSchoolyear.name, [Validators.minLength(3), Validators.required]);
this.endDateCtrl = new FormControl(this.createSchoolyear.endDate, Validators.required);
this.startDateCtrl = new FormControl(this.createSchoolyear.startDate, Validators.required);
this.bestGradeCtrl = new FormControl(this.createSchoolyear.bestGrade);
this.worstGradeCtrl = new FormControl(this.createSchoolyear.worstGrade, matchingGrades(this.bestGradeCtrl));

this.schoolyearForm = this.formBuilder.group({
  name: this.nameCtrl,
  endDate: this.endDateCtrl,
  startDate: this.startDateCtrl,
  bestGrade: this.bestGradeCtrl,
  worstGrade: this.worstGradeCtrl
});

<强>验证

export const matchingGrades = (equalControl: FormControl): ValidatorFn => {
  let subscribe: boolean = false;

  return (control: FormControl): { [key: string]: boolean } => {
    if (!subscribe) {
      subscribe = true;

      equalControl.valueChanges.subscribe(() => {
        control.updateValueAndValidity();
      });
    }

    return equalControl.value === control.value ? { 'equalGrades': true } : null;
  };
}