ERROR Error: Cannot find control with name: '[

2019-07-24 15:33发布

问题:

I'm working with Reactive Forms and I'm trying to pass my form down to child components, but I'm running into the error above. Initially at the top level of the form I was using a FormArray to hold my form and that was working fine before I tried passing it down to the child components. Thanks to this post I now know that the top level of a form should be a FormGroup and the FormArray should be a child of the FormGroup.

So now I am nesting my FormArray inside of a FormGroup and I'm getting the error above. I'm not sure what I'm doing wrong? Below in the relevant code.

// Parent component.ts

ngOnInit() {
    if (!!this.rows) {

        this.tableForm = new FormArray([]);

        this.rows.forEach((row) => {
            this.rowGroup = new FormGroup({})
            this.columns.forEach(column => {
                this.rowGroup.addControl(column.key, new FormControl(row[column.key]));
            });
            this.tableForm.push(this.rowGroup);
        })

        this.tableGroup = new FormGroup({
            rows: new FormControl(this.tableForm)
        })
    }
}

// Parent HTML

<section
    *ngIf="!!modal"
    class="modal__mask">
    <section
        class="modal__container"
        #carousel
        [ngStyle]="{'left': start + 'px'}"
        (window:resize)="onResize($event)"
        [formGroup]="tableGroup">

        <div
            *ngFor='let row of selectedRows; let i = index'
            class="modal modal__large"
            [formArrayName]="rows">
            <div
                [formGroupName]="i"
                [ngClass]="{'opacity': modalPage !== i}">
                <div class="modal__header modal__header--large">
                    <h6>Edit Employee Details</h6>
                </div>
                <div class="u-flex u-wrap">
                    <div
                        class="u-flex modal__body"
                        style="width: 50%"
                        *ngFor="let column of columns">
                        <div
                            *ngIf="column.label"
                            class="input__wrapper"
                            [ngClass]="{'input__wrapper--inline': layout === 'horizontal'}">
                            <z-input
                                *ngIf="column.label"
                                class="u-maxX"
                                [group]="tableGroup"
                                [config]="column"> 
                            </z-input>

                            <!-- <div>
                                    <label
                                        class="input__label">
                                        <p class="t-bold t-data">{{column.label}}</p>
                                    </label>
                                    <div class="z-input__default">
                                        <input
                                            class="input u-maxX"
                                         [formControlName]="column.key"
                                            [value]="row[column.key]">
                                    </div>
                                </div> -->

                        </div>
                    </div>
                    <section class="modal__footer u-fillRemaining">
                        <div class="u-flex">
                            <button
                                class="button button--medium"
                                (click)="nextSelectedRow()">
                                <div class="button__content">
                                    <i
                                        class="icon icon--medium"
                                        *ngIf="!!icon">
                                        {{icon}}
                                    </i>
                                    <span>Skip</span>
                                </div>
                            </button>
                        </div>
                        <div class="u-flex">
                            <button
                                class="button button--low"
                                (click)="reset(row, i)">
                                <div class="button__content">
                                    <i
                                        class="icon icon--medium"
                                        *ngIf="!!icon">
                                        {{icon}}
                                    </i>
                                    <span>Reset</span>
                                </div>
                            </button>
                            <button
                                class="button button--low"
                                (click)="saveChanges(row, i)">
                                <div class="button__content">
                                    <i
                                        class="icon icon--medium"
                                        *ngIf="!!icon">
                                        {{icon}}
                                    </i>
                                    <span>Save Changes</span>
                                </div>
                            </button>
                        </div>
                    </section>
                </div>
            </div>
        </div>

// Child component.ts

@Input() config;
@Input() group: FormGroup;
@Input() view: string;
@Input() layout: string;

// Child HTML

<div
    class="input__wrapper"
    [ngClass]="{'input__wrapper--inline': layout === 'horizontal'}"
    [formGroup]="group"
    [ngSwitch]="config.type">
    <label
        class="input__label"
        *ngIf="!!config.label">
        <p class="t-bold t-data">{{config.label}}</p>
    </label>

    <z-select
        *ngSwitchCase="'select'"
        [config]="config"
        [group]="group"
        [view]="view"
        gridColumn="1 / 5">
    </z-select>

    <div class="z-input__default">
        <input
            *ngSwitchDefault
            class="input u-maxX"
            [formControlName]="config.key"
            [attr.type]="config.type"
            [attr.placeholder]="config.placeholder">
    </div>