angular - 嵌套 FormGroup 的 FormControl 是 ng-valid 尽管 FromGroup 是 ng-invalid

标签 angular angular2-forms

我有一个名为“成绩”的嵌套表单组:

尽管嵌套表单组“grades”应用了 ng-invalid 类,但子表单控件确实应用了 ng-valid 类。

为什么失效没有从嵌套表单继承到它的控件?

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],
  grades: this.formBuilder.group({
    bestGrade: [this.createSchoolyear.bestGrade, Validators.required],
    worstGrade: [this.createSchoolyear.worstGrade, Validators.required]
  }, { validator: this.gradesCompare })
});


  gradesCompare(c: AbstractControl): { [key: string]: boolean } | null
  {
    let bestGradeControl = c.get("bestGrade");
    let worstGradeControl = c.get("worstGrade");

    if (bestGradeControl.pristine || worstGradeControl.pristine)
      return null;

    if (bestGradeControl.value === worstGradeControl.value)
    {
      return { "match": true };
    }
    return null;
  }

查看红色和绿色边框:

enter image description here

在 FormControl 上是未应用的 css ng-invalid 类:

.ng-valid:not(form)  {
  border-left: 5px solid #42A948; /* green */
}

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

因此它们的边框是绿色的,但我希望它们是红色的!

更新

我把用户 Ben 的 plunkr 改成了这个:

https://plnkr.co/edit/VobcC0Qw1EBDytYdkzru?p=preview

它按我希望的那样工作,但对我来说这似乎是一种解决方法。多个 ng-class 表达式很难理解...

请 Ben 捕获这个 plunkr 作为你的,将其作为解决方案发布,但前提是你诚实地认为你也会对解决方案感到满意。如果没有,请尝试找到更好的解决方案,既然您已经完全了解我的要求。

也欢迎其他人加入这个挑战,既然您知道验证/用户界面/错误消息应该如何真正表现。

最佳答案

从技术上讲,特定的表单控件 bestGradeworstGrade 根据它们自己的验证器是有效的。只有他们的组有错误。如果组无效,Angular 无法知道您希望使哪些控件无效。如果您愿意,您可以将是否存在特定组验证错误的信息添加到特定控件上,这将导致它们在无效时或它们的组有匹配错误时带有红色边框。

如果没有默认值,当控件自身有效(满足所需条件)时, Angular 进程组验证和控件验证的顺序将覆盖在控件上手动添加的任何 ng-invalid。这就是为什么我在这里使用另一个类 ma​​tchError 而不是 ng-invalid。否则 ng-invalid 将被删除并替换为 ng-validng-invalid 被 ngClasses 或等效类修改添加后的控件验证.

所以代替

<select formControlName="bestGrade">

你可以用

<select [class.matchError]="schoolyearForm.get('grades').hasError('match')" formControlName="bestGrade">

同理,代替

<select formControlName="worstGrade">

你可以使用

<select [class.matchError]="schoolyearForm.get('grades').hasError('match')" formControlName="worstGrade">

编辑: 由于 OP 在使用选择标签而不是输入(阅读聊天)时仍然存在问题,我建议还从验证器本身中删除双重原始要求(按照惯例,我们通常会在显示错误的地方检查它)。因为 OP 仍然有问题,我准备了一个 plunkr 来演示他的应用程序的工作虚拟(和丑陋)版本来帮助调查这个问题。

plunkr 可以在以下位置找到:

https://plnkr.co/edit/Gt5skDUOXfEaxsZreOkh

编辑 2:更新 plnkr URL 以处理在组和单个组控件之间检查验证时的类设置顺序

编辑 3:调整此处本身的答案以反射(reflect) OP 对没有默认值的需求,因为已经在编辑 2 的最新 plnkr 中设置

关于angular - 嵌套 FormGroup 的 FormControl 是 ng-valid 尽管 FromGroup 是 ng-invalid,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42354697/

相关文章:

angular - 如何使用 TypeScript 在 Angular 2 中根据出生日期计算年龄

angular - Angular 2中的动态管道

file-upload - 如何在 Angular2 react 形式中包含文件上传控件?

Angular2 自定义表单控件防止发出事件

angular - 清除按钮未重置 Angular 6 下拉列表中的选定值

Angular2 在构建简单表单时没有 ControlContainer 的提供者

angular - 如何设置igxDialog的宽高?

Angular ngOnChanges detectorChanges 在更新嵌套数据绑定(bind)之前发生

angular - Docker nginx 代理 websocket 获取 404

angular - 使用 Angular 2 通过回车键关注下一个输入字段