Angular Deeply Nested Reactive Form: Cannot find control with path on nested FormArray

前端 未结 1 699
说谎
说谎 2020-12-06 23:50

I am building a nested, dynamic Form where the User has a group, and then can nest conditions within that group, or new additional group objects within a group

相关标签:
1条回答
  • 2020-12-07 00:23

    I've written a post at dev.to after writing this answer. Take a look.


    You're dealing with a complex form. It's nested and it's recursive (as you have groups in groups). I suggest you split it into more components. By doing that, you'll make it easier to have a big picture of the whole form whenever you revisit it for any reason. And, as a very welcome cherry-on-the-cake, you will avoid the deeply nested object paths you're using to access your controls (this can be overwhelming as you keep nesting dynamic forms the way you're doing).

    What I'm trying to say is that the error is likely caused by some silly mistake in the deep object paths you use to get access to the form parts. When dealing with this kind of complex nested form, it usually isn't worth the effort to fix eventual issues related to wrong object paths: refactor it to get a more clean-structured component.

    I strongly suggest you do the two things I'll describe below (also, take a look at this Stackblitz demo). What I did in that demo is a complete refactor of your form and I decided not to paste all the code here because it would be excessively long, hard to read, and you wouldn't be able to execute it anyway. So it would be pointless. Just go to the Stackblitz demo and try it there.

    Your form has a very peculiar aspect: it's recursive. So everything is gonna be easier if we don't try to row the boat against its recursive nature stream.

    I assure you I did nothing special in that code but just these two steps:

    1 - Create a wrapper recursive form component:

    Let's call it GroupFormComponent. The one thing that's not so common here is that, in the template of this component, you're gonna have... another GroupFormComponent. Yes, you can bury an angular component inside itself recursively.

    @Component({
      selector: 'group-form',
      template: `
        ...
        <!-- here you nest another instance of this component -->
        <group-form *ngIf="nestCondition"></group-form>
        ...
      `,
    })
    export class GroupFormComponent {...}
    
    

    The above snippet helps to illustrate what I'm suggesting you do (this kind of structure shows how far you can go with angular component-based nature => it's powerful, isn't it?).

    2 - Split your form into more controls

    You can (and should) group some parts of your form into other components, to make it easier to be understood as a whole. Without any great mental effort, we can identify three components:

    • The main form, containing the overall form

    • A bar of action buttons

    • A condition component

    When you assemble all these parts together, you'll get:

    <main-form>
      <action-buttons></action-buttons>
      <condition></condition>
      <condition></condition>
      ...
      <condition></condition>
    
      <!-- The recursive part -->
      <main-form></main-form>
      <main-form></main-form>
      ...
      <main-form></main-form>
    </main-form>
    

    To make it even more simple, <condition> and <main-form> components must implement the ControlValueAccessor interface in order to allow them to be used as FormControl's in other forms.

    With all these this in place, you'll have a robust, maintainable, and flexible form.

    The animated gif below shows it working.

    0 讨论(0)
提交回复
热议问题