Angular 如何将表单组绑定到嵌套动态创建的组件
How to bind form group to nested dynamically created components in Angular
在我的 Angular 12 应用程序中,我有这种层次结构:
- app.component
-- Parent component with form (reactive)
--- Component that creates the dynamic components
---- Dynamic component
我的 formBuilder 表单如下所示:
form = this.fb.group({
baseLevelControl: ["base control"],
groupOfGroups: [this.fb.group({
innerGroup1: this.fb.group({
dummy1Control1: "control 1 from inner group 1",
dummy1Control2: "control 2 from inner group 1",
}),
innerGroup2: this.fb.group({
dummy2Control1: "control 1 from inner group 2",
dummy2Control2: "control 2 from inner group 2",
}),
})]
});
我的动态组件只需要知道 groupOfGroups 而不是整个表单,因为它将在许多地方使用不同种类的表单。
当我在动态组件中设置时
<div [formGroup]="innerForm">
我得到一个不与父窗体通信的独立窗体。
如果我使用
<div formGroupName="innerForm">
我收到错误 formGroupName must be used with a parent formGroup directive
如何正确绑定 groupOfGroups?
我创建了 this stackblitz project 来模拟这个问题,任何帮助将不胜感激
您可以在子组件中注入 ControlContainer
以访问父组件表单组。
在您的子 dynamic1.component.ts
组件中,注入 ControlContainer 并将父表单组分配给子组件的 FormGroup
属性。这将使您可以从父组件访问父组件 FormGroup
。
@Component({
selector: 'app-dynamic1',
templateUrl: './dynamic1.component.html',
styleUrls: ['./dynamic1.component.scss'],
})
export class Dynamic1Component implements OnInit {
public formGroup: FormGroup;
constructor(private _parentContainer: ControlContainer) {}
ngOnInit(): void {
this.formGroup = this._parentContainer.control as FormGroup;
}
}
更新您的 dynamic1.component.html
以使用此表单群组。
<div *ngIf="formGroup" [formGroup]="formGroup">
<div formGroupName="innerGroup1">
<p>dummy controls for group 1</p>
<input formControlName="dummy1Control1" />
<input formControlName="dummy1Control2" />
</div>
<div formGroupName="innerGroup2">
<p>dummy controls for group 2</p>
<input formControlName="dummy2Control1" />
<input formControlName="dummy2Control2" />
</div>
</div>
在您的 level1.component.ts
中更新 FormGroup。您最初将 groupOfGroups
作为数组。这不是必需的,您可以简单地为此分配一个 FormGroup。
@Component({
selector: 'app-level1',
templateUrl: './level1.component.html',
styleUrls: ['./level1.component.scss'],
})
export class Level1Component implements OnInit {
form = this.fb.group({
baseLevelControl: ['base control'],
groupOfGroups: this.fb.group({
innerGroup1: this.fb.group({
dummy1Control1: 'control 1 from inner group 1',
dummy1Control2: 'control 2 from inner group 1',
}),
innerGroup2: this.fb.group({
dummy2Control1: 'control 1 from inner group 2',
dummy2Control2: 'control 2 from inner group 2',
}),
}),
});
// OTHER STUFF....
}
您的 level1.component.html
模板看起来像...
<h1>Level 1</h1>
<div [formGroup]="form">
<label for="baseControl">Base Control Value:</label>
<input name="baseControl" formControlName="baseLevelControl" type="text" />
<div formGroupName="groupOfGroups">
<h3>Dynamic 2</h3>
<app-dynamic1></app-dynamic1>
</div>
<div>
<button type="button" (click)="onSubmit()">Submit</button>
</div>
</div>
在我的 Angular 12 应用程序中,我有这种层次结构:
- app.component
-- Parent component with form (reactive)
--- Component that creates the dynamic components
---- Dynamic component
我的 formBuilder 表单如下所示:
form = this.fb.group({
baseLevelControl: ["base control"],
groupOfGroups: [this.fb.group({
innerGroup1: this.fb.group({
dummy1Control1: "control 1 from inner group 1",
dummy1Control2: "control 2 from inner group 1",
}),
innerGroup2: this.fb.group({
dummy2Control1: "control 1 from inner group 2",
dummy2Control2: "control 2 from inner group 2",
}),
})]
});
我的动态组件只需要知道 groupOfGroups 而不是整个表单,因为它将在许多地方使用不同种类的表单。
当我在动态组件中设置时
<div [formGroup]="innerForm">
我得到一个不与父窗体通信的独立窗体。 如果我使用
<div formGroupName="innerForm">
我收到错误 formGroupName must be used with a parent formGroup directive
如何正确绑定 groupOfGroups?
我创建了 this stackblitz project 来模拟这个问题,任何帮助将不胜感激
您可以在子组件中注入 ControlContainer
以访问父组件表单组。
在您的子 dynamic1.component.ts
组件中,注入 ControlContainer 并将父表单组分配给子组件的 FormGroup
属性。这将使您可以从父组件访问父组件 FormGroup
。
@Component({
selector: 'app-dynamic1',
templateUrl: './dynamic1.component.html',
styleUrls: ['./dynamic1.component.scss'],
})
export class Dynamic1Component implements OnInit {
public formGroup: FormGroup;
constructor(private _parentContainer: ControlContainer) {}
ngOnInit(): void {
this.formGroup = this._parentContainer.control as FormGroup;
}
}
更新您的 dynamic1.component.html
以使用此表单群组。
<div *ngIf="formGroup" [formGroup]="formGroup">
<div formGroupName="innerGroup1">
<p>dummy controls for group 1</p>
<input formControlName="dummy1Control1" />
<input formControlName="dummy1Control2" />
</div>
<div formGroupName="innerGroup2">
<p>dummy controls for group 2</p>
<input formControlName="dummy2Control1" />
<input formControlName="dummy2Control2" />
</div>
</div>
在您的 level1.component.ts
中更新 FormGroup。您最初将 groupOfGroups
作为数组。这不是必需的,您可以简单地为此分配一个 FormGroup。
@Component({
selector: 'app-level1',
templateUrl: './level1.component.html',
styleUrls: ['./level1.component.scss'],
})
export class Level1Component implements OnInit {
form = this.fb.group({
baseLevelControl: ['base control'],
groupOfGroups: this.fb.group({
innerGroup1: this.fb.group({
dummy1Control1: 'control 1 from inner group 1',
dummy1Control2: 'control 2 from inner group 1',
}),
innerGroup2: this.fb.group({
dummy2Control1: 'control 1 from inner group 2',
dummy2Control2: 'control 2 from inner group 2',
}),
}),
});
// OTHER STUFF....
}
您的 level1.component.html
模板看起来像...
<h1>Level 1</h1>
<div [formGroup]="form">
<label for="baseControl">Base Control Value:</label>
<input name="baseControl" formControlName="baseLevelControl" type="text" />
<div formGroupName="groupOfGroups">
<h3>Dynamic 2</h3>
<app-dynamic1></app-dynamic1>
</div>
<div>
<button type="button" (click)="onSubmit()">Submit</button>
</div>
</div>