【问题标题】:Angular Dynamically resolved components using nested Reactive Forms with CVA's are not working使用带有 CVA 的嵌套反应表单的 Angular 动态解析组件不起作用
【发布时间】:2021-02-26 18:33:37
【问题描述】:

啊,使用 ReactiveForms 动态构建组件时遇到问题。

需要触发和 Mat-Dialog 并在其中加载一组组件 - 工作正常。 需要从 映射数组 动态构建一些组件 - 工作正常。 需要使用 CVA(控制值评估器) 构建嵌套的反应式表单 - 这就是问题所在。

我有一个使用 CVA 的嵌套表单,可以正确更新表单数据……除非我动态构建组件。如果我使用动态组件,它们会在表单更新中被忽略。不知道如何解决这个问题。我的应用将是非常复杂的表单网络,所以需要弄清楚这一点!

我已经使用了 Angular.io 动态组件指南。

Angular.io - resolve dynamic components

并按照本指南进行 CVA 实施

In-Depth - using CVA's

有人有什么想法吗? Stackblitz 有问题,所以将代码推送到 gitHub

dev-dynamic-comp issue

【问题讨论】:

    标签: angular reactive-forms angular-dynamic-components controlvalueaccessor


    【解决方案1】:

    我们可以使用 ControlContainer 向父 FormGroup 注册我们的子表单,而不是使用 CVA 使用子表单组件方法来创建 app-content 表单。

    在子组件中注入 ControlContainer 提供对父 FormGroup 的访问,然后我们可以使用 addControl 方法添加所需的表单控件。

    content.component.ts

    import { Component, forwardRef, OnInit } from '@angular/core';
    import { AbstractControl, ControlContainer, ControlValueAccessor, FormControl, FormGroup, NG_VALIDATORS, NG_VALUE_ACCESSOR, ValidationErrors, Validators } from '@angular/forms';
    
    @Component({
      selector: 'app-content',
      templateUrl: './content.component.html',
      styleUrls: ['./content.component.scss']
    })
    export class ContentComponent implements OnInit {
    
      parent:FormGroup;
      constructor(private controlContainer:ControlContainer) { }
    
      ngOnInit(): void {
        this.parent = this.controlContainer.control as FormGroup;
         this.parent.addControl('contentInfoForm',new FormGroup({
          contentNotes: new FormControl("",[Validators.required]),
          contentData: new FormControl("", [Validators.required])
        }));
      }
    }
    

    component.html

    <ng-container *ngIf="parent" [formGroup]="parent">
        <ng-container formGroupName="contentInfoForm">
            <div class="row">
                <label for="Content Notes"> Content Notes </label>
                <input type="text" formControlName="contentNotes" class="">
        </div>
                <div class="row">
                    <label for="Content Data"> Content Data </label>
                    <input type="text" formControlName="contentData" class="">
        </div>
        </ng-container>
    </ng-container>
    

    Forked Working Example

    【讨论】:

    • 谢谢@chellappan。这看起来不错。我实际上首先尝试了这种方法,但一定是搞砸了。将尝试此解决方案,看看它是否有效,然后报告结果。
    • 好吧,我终于让 controlGroup 实现适用于我的功能。仍然收到 expressionChanged 错误。我尝试使用 AfterViewInit 而不是 OnInit 但出现更多错误。
    • 所以我已经在我的实际应用程序上尝试了您的解决方案并取得了同样的成功 - 表单最终与父级通信。谢谢,我尝试了很多不同的解决方案,这是唯一适合我的解决方案。
    • 是的 - 仍然出现 expressionChanged 错误,例如。 ERROR 错误:ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。以前的值:'{“formTitle”:“”,“basicInfo”:“”,“addressInfo”:“”,“specialInfo”:“”}'。当前值:'{“formTitle”:“”,“basicInfo”:“”,“addressInfo”:“”,“specialInfo”:“”,“contentInfoForm”:{“contentNotes”:“”,“contentData”:“ “ } }”。在 throwErrorIfNoChangesMode (core.js:8160) ... ... ... 在 DialogComponent_Template (dialog.component.html:16)
    • 如果您在 OnInit 中移动表单创建也会引发错误?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-04
    • 1970-01-01
    • 2017-07-20
    • 2019-02-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    相关资源
    最近更新 更多