angular 中的嵌套动态表单 - 无法读取未定义的 属性 'controls'
Nested dynamic form in angular - Cannot read property 'controls' of undefined
我正在尝试建立一个网站,提供上传您自己的课程的功能。
课程结构
Name of course
|-Module1
|-Lecture1
|-Lecture2
|-Module2
|-Lecture1
|-Lecture2
使用 Angular 我正在尝试创建一个动态表单,它将 add/remove 课程中的模块和模块中的讲座
到目前为止,我已经写了以下内容 -
课程-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
我用 ** > **
突出显示了引发错误的行
有帮助吗?
我认为你必须检查给定的数组是否为空。如果为空,你应该 return null,
getModulesControls(i: number) {
if(this.courseUploadForm.controls.modules.length <1){
return null;
}
else{
return [(this.courseUploadForm.controls.modules as FormArray).controls[i]['controls']];
}
}
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)
此外,HTML 文件的第 5 行变量 module
被定义为一个对象。第 23 行 module.get('lectures')
看起来您希望 module
变量中有一个 FormGroup
。看看this example from Angular docs。注意 HTML 标记和 TS。您将需要创建几个吸气剂,例如 get cities(): FormArray
(:
我正在尝试建立一个网站,提供上传您自己的课程的功能。
课程结构
Name of course
|-Module1
|-Lecture1
|-Lecture2
|-Module2
|-Lecture1
|-Lecture2
使用 Angular 我正在尝试创建一个动态表单,它将 add/remove 课程中的模块和模块中的讲座
到目前为止,我已经写了以下内容 -
课程-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
我用 ** > **
突出显示了引发错误的行有帮助吗?
我认为你必须检查给定的数组是否为空。如果为空,你应该 return null,
getModulesControls(i: number) {
if(this.courseUploadForm.controls.modules.length <1){
return null;
}
else{
return [(this.courseUploadForm.controls.modules as FormArray).controls[i]['controls']];
}
}
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)
此外,HTML 文件的第 5 行变量 module
被定义为一个对象。第 23 行 module.get('lectures')
看起来您希望 module
变量中有一个 FormGroup
。看看this example from Angular docs。注意 HTML 标记和 TS。您将需要创建几个吸气剂,例如 get cities(): FormArray
(: