Вложенная динамическая форма c в angular - Невозможно прочитать «элементы управления» свойства undefined - PullRequest
2 голосов
/ 16 июня 2020

Я пытаюсь создать веб-сайт, который предоставляет возможность загрузки ваших собственных курсов.

Структура курса

    Name of course
    |-Module1
      |-Lecture1
      |-Lecture2
    |-Module2
      |-Lecture1
      |-Lecture2

Используя Angular Я пытаюсь создать динамическую c форму, которая будет добавлять / удалять модули внутри курса и лекции в модуле

Пока что я написал следующее -

course-upload.component.ts

export class CourseUploadComponent implements OnInit {

    courseUploadForm: FormGroup;

    constructor(private formBuilder: FormBuilder) { }

    ngOnInit() {
        this.courseUploadForm = this.formBuilder.group({
            coursename: ['', Validators.required],
            modules: this.formBuilder.array([
                this.initModules()
            ])
        })
    }

    initModules() {
        return this.formBuilder.group({
            modulename: ['', Validators.required],
            lectures: this.formBuilder.array([
                this.initLecture()
            ])
        });
    }

    initLecture() {
        return this.formBuilder.group({
            lecturename: ['', Validators.required],
            description: ['', Validators.required],
            lecture: ['', Validators.required]
        });
    }

    addModule() {
        const control = <FormArray>this.courseUploadForm.get('modules');
        control.push(this.initModules());
    }

    addLecture() {
        const control = <FormArray>this.courseUploadForm.get('lectures');
        control.push(this.initLecture());
    }

    removeModule(i: number) {
        const control = <FormArray>this.courseUploadForm.get('modules');
        control.removeAt(i);

    } 

    removeLecture(i: number) {
        const control = <FormArray>this.courseUploadForm.get('lectures');
        control.removeAt(i);
    }

    getModulesControls(i: number) {
        >>>> return [(this.courseUploadForm.controls.modules as FormArray).controls[i]['controls']];
    }

    getLecturesControls(i: number) {
        return [(this.courseUploadForm.controls.lectures as FormArray).controls[i]['controls']];
    }

}

курс -upload.component. html

<form [formGroup]="courseUploadForm" novalidate>

    <div formArrayName="modules">

        <mat-card *ngFor="let module of courseUploadForm.get('modules').value; let i=index">

            <mat-card-subtitle>
                {{i+1}}
            </mat-card-subtitle>

            <div [formGroupName]="i">

                <mat-form-field>
                    <mat-label>Module Name</mat-label>
                   **>>>** <input matInput placeholder="Module Name" formControlName="modulename">
                    <ng-container *ngFor="let control of getModulesControls(j)">
                        <mat-error *ngIf="!control.name.valid">Name Required</mat-error>
                    </ng-container>
                </mat-form-field>

                <div formArrayName="lectures">

                    <mat-card *ngFor="let lecture of module.get('lectures').value; let j=index">

                        <mat-card-subtitle>
                            Lecture {{i+1}}: {{lecture.name}}
                        </mat-card-subtitle>

                        <div [formGroupName]="j">

                            <mat-form-field>
                                <mat-label>Name</mat-label>
                                <input matInput placeholder="Lecture Name" formControlName="lecturename">
                                <ng-container *ngFor="let control of getLecturesControls(j)">
                                    <mat-error *ngIf="!control.name.valid">Name Required</mat-error>
                                </ng-container>
                            </mat-form-field>

                            <mat-form-field>
                                <mat-label>Description</mat-label>
                                <input matInput placeholder="Lecture Description" formControlName="description">
                                <ng-container *ngFor="let control of getLecturesControls(j)">
                                    <mat-error *ngIf="!control.description.valid">Description Required</mat-error>
                                </ng-container>
                            </mat-form-field>

                            <mat-form-field>
                                <mat-label>Lecture</mat-label>
                                <input matInput placeholder="Lecture Video" formControlName="lecture">
                                <ng-container *ngFor="let control of getLecturesControls(j)">
                                    <mat-error *ngIf="!control.lecture.valid">Lecture Video Required</mat-error>
                                </ng-container>
                            </mat-form-field>
                            <mat-card-actions>
                                <button mat-raised-button color="accent" (click)="addLecture()">Add Another
                                    Lecture</button>
                                <button mat-raised-button color="warn"
                                    *ngIf="module.get('lectures')['controls'].length > 1"
                                    (click)="removeLecture(j)">Remove This Lecture</button>
                            </mat-card-actions>
                        </div>

                    </mat-card>

                </div>
                <mat-card-actions>
                    <button mat-raised-button color="accent" (click)="addModule()">Add Another Module</button>
                    <button mat-raised-button color="warn"
                        *ngIf="courseUploadForm.get('modules')['controls'].length > 1" (click)="removeModule(i)">Remove
                        This Module</button>
                </mat-card-actions>
            </div>

        </mat-card>

    </div>

</form>

Я получаю сообщение об ошибке:

Cannot read property 'controls' of undefined

at CourseUploadComponent.getModulesControls 

at CourseUploadComponent_mat_card_2_Template 

Я выделил строки, которые вызывают ошибку с **> **

Помощь?

Ответы [ 2 ]

2 голосов
/ 16 июня 2020

j здесь не определено, оно должно было отличаться от smg

<ng-container *ngFor="let control of getModulesControls(j)">
    <mat-error *ngIf="!control.name.valid">Name Required</mat-error>
</ng-container>

Я полагаю, вы хотели использовать здесь переменную i: getModulesControls(i)

Кроме того, строка 5 файла HTML переменная module определена как объект. Строка 23 module.get('lectures') выглядит так, как будто вы ожидаете FormGroup в переменной module. Взгляните на этот пример из Angular docs . Обратите внимание как на разметку HTML, так и на TS. Вам нужно будет создать несколько геттеров, например get cities(): FormArray (:

0 голосов
/ 16 июня 2020

Я думаю, вам нужно проверить свой массив пустым или нет. Если пусто, вы должны вернуть ноль,

    getModulesControls(i: number) {
         if(this.courseUploadForm.controls.modules.length <1){
              return null;
         }
         else{
             return [(this.courseUploadForm.controls.modules as FormArray).controls[i]['controls']];
         }
    }
...