嵌套 FormGroup 的 FormControl 是 ng-valid,虽然 FromGroup 是 ng-invalid [英] FormControl`s of nested FormGroup are ng-valid although FromGroup is ng-invalid

查看:19
本文介绍了嵌套 FormGroup 的 FormControl 是 ng-valid,虽然 FromGroup 是 ng-invalid的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a nested form group called 'grades':

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

Although the nested form group 'grades' has the ng-invalid class applied the children form controls do have applied the ng-valid class.

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

Why is the invalidation not inherited from the nested form to its controls?

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;
  }

查看红色和绿色边框:

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

On the FormControl`s are the css ng-invalid classes not applied:

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

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

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

Therefore they are bordered green, but I expected them to be red!

更新

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

I changed the plunkr of user Ben to this one:

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

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

It works as I wished it would work, but it seems like a workaround to me. The multiple ng-class expression are hard to understand...

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

Please Ben grab this plunkr as yours, post it as solution, but only if you think honestly you would also be satisfied with the solution. If not try to find a better solution please, now that you fully know my requirements.

也欢迎其他人加入这个挑战,现在您知道验证/ui/error-messages 应该如何真正表现.

Others are also welcome to join this challenge, now that you know how the validation/ui/error-messages should really behave.

推荐答案

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

Technically, the specific form controls bestGrade and worstGrade are valid according to their own validators. Only their group has an error. Angular can't know you which controls you would want to invalidate if the group becomes invalid. You could make the information whether there was that specific group validation error onto the specific controls if you wished, and this would result in them being bordered red when they are invalid OR their group has the match error.

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

Without default, the order in which angular processes group validation and control validation would override any manual adding of ng-invalid on the control when the control becomes valid on its own (required condition fulfilled). This is why I am using another class here matchError rather than ng-invalid. Otherwise ng-invalid would be removed and replaced by ng-valid by the control validation after ng-invalid is added by ngClasses or equivalent class modification.

所以代替

<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 演示他的应用程序的工作虚拟(和丑陋)版本,以帮助调查该问题.

As OP still had issues while using select tags instead of input (read chat), I have recommended also removing the double pristine-ness requirement from the validator itself (by convention, we normally would check this where errors are displayed instead). Because the OP still has issues, I have prepared a plunkr demonstrating a working dummy (and ugly) version of his app to help investigate the issue.

可以在以下位置找到 plunkr:

The plunkr can be found at:

https://plnkr.co/edit/Gt5skDUOXfEaxsZreOkh

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

Edit 2: plnkr URL updated to deal with class setting order when validation are checked between group and individual group controls

编辑 3:在这里调整了答案本身,以反映 OP 对没有默认值的需求,因为编辑 2 的最新 plnkr 中已经设置了

Edit 3: Adjusted the answer here itself to reflect the OP's need for without defaults as was already setup in the latest plnkr from Edit 2

这篇关于嵌套 FormGroup 的 FormControl 是 ng-valid,虽然 FromGroup 是 ng-invalid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆