首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使父FormGroup无效,直到嵌套的FormGroups有效--自定义FormGroup验证器

使父FormGroup无效,直到嵌套的FormGroups有效--自定义FormGroup验证器
EN

Stack Overflow用户
提问于 2018-12-05 17:13:35
回答 1查看 1.3K关注 0票数 6

我有一个Range7项目,用于动态创建表单。我有一个父FormGroup和不同类型的嵌套FormGroups。

我希望parentForm是无效的,直到所有嵌套/子表单都是有效的(实际上希望它们被提交,但还没有达到)。

代码语言:javascript
复制
  this.parentForm = new FormGroup(this.subforms, { validators: allSubModulesValidValidator }); 

this.subforms是这样一个对象:

代码语言:javascript
复制
interface DynamicKeyFormGroup {
  [key: string]: FormGroup;
}

subforms: DynamicKeyFormGroup = {};

我知道我的验证器是错误的,但是我不知道如何为FormGroup和FormControl设计一个验证器。

我的想法是,我试图循环所有this.subForms的属性,这些属性是嵌套的FormGroups,然后检查它们的状态。如果有无效的,将parentForm标记为无效。

代码语言:javascript
复制
const allSubModulesValidValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
  const controls = control.controls;
  for (const key in controls) {
    if (controls.hasOwnProperty(key)) {
      if (!(controls[key].status === 'valid')) {
        return { 'allSubModulesValid': true };
      }
    }
  }
  return null;
};

以回应评论。删除验证器后,父程序有效,而子验证程序无效:

EN

回答 1

Stack Overflow用户

发布于 2022-07-12 21:04:39

在我看来,这是一个角度错误,尽管如上面的clearValidators注释所示,它是预期的行为。

所以让我们看看发生了什么。

我假设您正在清除验证器(基于图像),方法之一是

代码语言:javascript
复制
someControl.validator = null;

这是有点不合适的,或者通过调用明确的验证器函数。

代码语言:javascript
复制
someControl.clearValidators()

根据角源进行以下操作

代码语言:javascript
复制
  /**
   * Empties out the synchronous validator list.
   *
   * When you add or remove a validator at run time, you must call
   * `updateValueAndValidity()` for the new validation to take effect.
   *
   */
  clearValidators(): void {
    this.validator = null;
  }

如图所示,GithubSource是一样的。

所以问题是,这种状态清除不会更新控件及其父母的状态。

为了在清除状态后修复此行为,您应该更新控件。

代码语言:javascript
复制
someControl.clearValidators();
someControl.updateValueAndValidity();

updateValueAndValidity将更新控件的当前状态,并通知父FormGroup (如果有的话)。

@ provided:stackBlitz在上面的注释中提供的示例将工作,即使您清除了验证器,因为他正在调用控件的setValue方法,该方法执行以下操作

代码语言:javascript
复制
      override setValue(value: TValue, options: {
        onlySelf?: boolean,
        emitEvent?: boolean,
        emitModelToViewChange?: boolean,
        emitViewToModelChange?: boolean
      } = {}): void {
        (this as {value: TValue}).value = this._pendingValue = value;
        if (this._onChange.length && options.emitModelToViewChange !== false) {
          this._onChange.forEach(
              (changeFn) => changeFn(this.value, options.emitViewToModelChange !== false));
        }
        this.updateValueAndValidity(options);
      }

正如在角源中看到的那样,这将调用内部updateValueAndValidity,它将更新状态。

三年后,船长来到这里:D

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53637481

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档