反应形式始终有效,即使无效.嵌套儿童的形式 [英] Reactive Form Always Valid, Even When Not. Nested Children in Form

查看:79
本文介绍了反应形式始终有效,即使无效.嵌套儿童的形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看到了与此问题相关的一些StackOverflow问题,但似乎没有一个能证明行之有效的答案.

I have seen a few StackOverflow issues with this question, but none of them seem to have proven answers that work.

我正在使用Angular构建动态创建的反应形式. 此处的StackBlitz .用户可以选择添加组",然后选择添加".和条件"在组内.每个组都可以使用FormArrays进一步嵌套.

I am building a dynamically created Reactive Form Using Angular. StackBlitz here . The user has the option to add "groups" and "conditions" within the groups. Each group can be further nested using FormArrays.

该表格可以正常工作.以下是表单的主要部分:

The form works as expected. Here are the main pieces of the form:

  1. AppComponent:主要的父组件
  2. GroupControlComponent:父级的子级.照顾所有的组对象
  3. ConditionFormComponent:GroupControlComponent的子级.照顾团体中的所有情况

这是基本对象的样子:

{
  // appcomponent level
  "statement": {
    //groupcontrol level
    "groups": [
      {
        // conditionform level
        "conjunctor": null,
        "conditions": [
          {
            "variable": null
          }
        ],
        "groups": []
      }
    ]
  }
}

设置验证时,我希望一切都必需.因此,我遍历了父级和子级组件上的FormBuilder,并将所有窗体控件上的Validators.required设置为true.

When I set up validation, I want everything to be required. So I went through the FormBuilder, on the parent and children components, and set Validators.required to true on all form controls.

this._fb.control({
  conjunctor: null,
  conditions: [[], Validators.required],
  groups: [[], Validators.required]
 })

(所有控件都是这种情况)

(this is the case on all controls)

问题在于,现在始终的表格是有效的.即使该表格实际上无效.使用嵌套的子组件时可以检查表单的有效性吗?

The problem is, the form now always is valid. Even when the form is not actually valid. Is it possible to check form validity while using nested child components?

如果需要,这里是有关此特定表格的更多信息:

Here is some more information about this specific form, if required:

找不到控件在递归角形式上使用ngIf进行路径操作

>深度嵌套的角度反应形式:在嵌套FormArray上找不到带有路径的控件

推荐答案

Stackblitz演示

基本上,您必须实现Validator(不是Validators-复数)接口.它具有一种强制性方法:

Basically you must implement the Validator (not Validators - plural) interface. It has one mandatory method:

validate(c: AbstractControl) => ValidationErrors;

如果控件有效,则方法validate应该返回null,如果控件无效,则返回任何其他对象.

The method validate should return null if the control is valid and any other object if it is invalid.

另一件事是,您必须以提供NG_VALUE_ACCESSOR的相同方式提供NG_VALIDATORS(现在使用复数).

One more thing is that you must provide NG_VALIDATORS (now, using plural) in the same way you provided NG_VALUE_ACCESSOR.

总结:

@Component({
  ...

  providers: [
    ...
    {
      provide: NG_VALIDATORS,
      useExisting: forwardRef(() => GroupControlComponent),
      multi: true
    }
  ]
})
export class GroupControlComponent implements Validator {
  ...

  // Notice that we don't need to use the c parameter passed to the method.
  // We are using the `_form` instance property to verify what we need
  validate(c: AbstractControl): ValidationErrors {
    return this._form.valid ? null : {errors: 'form is invalid'}; 
  }
  ...
}

您必须对GroupControlComponentConditionFormComponent执行此操作.

You must do it to your GroupControlComponent and the ConditionFormComponent.

[UPDATE]:您还需要照顾动态创建的控件.在组控件内部,让我们看一下具有输入的单个组件:条件控件.代替:

[UPDATE]: You also need to take care of the dynamically created controls. Inside group control, let's look at the one single component that has an input: the condition control. Instead of:

_addCondition() {
  this._conditionsFormArray.push(
    this._fb.control({variable: null})
  );
}

您应该使用验证器初始化该控件,以检查variable的有效性,因为与variable属性关联的基础控件仅在用户与ConditionFormComponent内部的输入进行交互之后才将其检出.因此,您应该这样写:

You should initialize the control with a validator that checks for the validity of variable because the underlying control associated with the variable attribute will only check this out after the user interacts with the input inside the ConditionFormComponent. So, you should write it like this:

_addCondition() {
  this._conditionsFormArray.push(
    this._fb.control({variable: null}, 
      (c: AbstractControl) => 
          c.value && c.value.variable ? null : {'required': true}
    )
  );
}

这是一个验证功能,用于检查variable属性的有效性:

Where this is a validation function that checks for the validity of the variable attribute:

(c: AbstractControl) => 
    c.value && c.value.variable ? null : {'required': true}

如果不这样做,它将覆盖基础ConditionForm控件中的验证(该控件指出需要输入).并且您可能会有一个奇怪的状态,其中外部形式(在GroupControl中)无效,但是内部形式(在ConditionForm中)有效.在外部表单上进行验证时,您基本上甚至可以删除内部表单中的Validators.required并仅依赖于外部表单验证.

If you don't do that, it'll override the validation in the underlying ConditionForm control (which states that the input is required). And you could have a weird state where the outer form (in GroupControl) is invalid, but the inner form (in the ConditionForm) is valid. As you're validating it on the outer form, you basically could even remove the Validators.required in the inner form and rely just on the outer form validation.

这篇关于反应形式始终有效,即使无效.嵌套儿童的形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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