Angular 表单:如何动态添加/删除子表单组件
Posted
技术标签:
【中文标题】Angular 表单:如何动态添加/删除子表单组件【英文标题】:Angular form: How to dynamically add/remove subform Component 【发布时间】:2020-09-09 00:07:05 【问题描述】:我希望在主窗体中能够动态添加/删除子窗体。 子表单基于模型对象,并嵌入了一些东西:
使用从父表单组件传输的数据(用于选择输入选项) 具有事件触发onChange功能 可以在编辑模式下使用,这样可以允许表单预填然后我为这个子表单创建一个专用组件:
型号:
impoort Obj from ./Obj.model.ts
export class Foo
constructor(
public name: string,
public obj: Obj,
public bar: string
)
subform.component.ts:
@Component(
selector: 'ngx-subformcomp',
templateUrl: './subform.component.html',
styleUrls: ['./subform.component.scss']
)
export class SubformComponent implements OnInit, OnDestroy
@Input() objs: Obj[];
@Input() foodata?: Foo;
subForm: FormGroup;
showBar: boolean = true;
constructor(
private formBuilder: FormBuilder,
private loadingService: LoadingService,
)
ngOnInit(): void
initForm();
if (foodata)
//In case Edit mode
this.subForm.patchValue(
name: foodata.name,
obj: foodata.obj,
bar: foodata.bar,
);
if (foodata.obj.id == 1)
this.subForm.get('bar').setValidators([Validators.required]);
this.subForm.get('bar').updateValueAndValidity();
this.showbar = true;
else
this.subForm.patchValue( bar: '' );
this.subForm.get('bar').setValidators([]);
this.subForm.get('bar').updateValueAndValidity();
initForm()
this.subForm = this.formBuilder.group(
name: ['', [Validators.required],
obj: new FormControl('', [Validators.required, SelectedValue]),
bar: ['', [Validators.required],
,
validator: [... , ...]
);
onObjChange(event)
if (event == 1)
this.subForm.get('bar').setValidators([Validators.required]);
this.subForm.get('bar').updateValueAndValidity();
this.showbar = true;
else
this.subForm.patchValue( bar: '' );
this.subForm.get('bar').setValidators([]);
this.subForm.get('bar').updateValueAndValidity();
和html:
<form [formGroup]="subForm">
<div class="form-group">
<input id="name" class="form-control" formControlName="name" />
</div>
<div class="form-group">
<nb-select id="obj" formControlName="obj" (selectedChange)="onObjChange($event)">
<nb-option *ngFor="let option of objs" [value]="option.id"> option.label </nb-option>
</nb-select>
</div>
<div class="form-group">
<input *ngIf="showBar" id="bar" class="form-control" formControlName="bar" />
</div>
</form>
我现在尝试在我的主要表单中使用它,但我迷路了......
我这样定义了我的主要表单组件:
export class MainComponent implements OnInit, OnDestroy
objs:Obj[] = [....],
mainForm: FormGroup;
ngOnInit(): void
initForm();
initForm()
this.mainForm = this.formBuilder.group(
foobar: ['', [Validators.required],
objs: this.formBuilder.array([]),
,
validator: [... ,...]
);
getObjs(): FormArray
return this.sMainForm.get('objs') as FormArray;
onAddObj()
在我的模板中:
<div class="form-group">
<ng-container formArrayName="objs" *ngFor="let obj of objs; let i=index">
<ngx-subformcomp id="'gsprice_'+i" [formControlName]="objs[i]"></ngx-subformcomp>
</ng-container>
<button (click)="onAddObj()" outline>Add</button>
</div>
我不知道如何对待 onAddObj 函数和即将到来的 removeObj... 谢谢你的帮助
【问题讨论】:
【参考方案1】:我在这里看到很多混乱(:
首先,这不是您可以迭代FormArray
的方式。正确的方法是
<div *ngFor="let ctr of objs.controls;">
这样ctr
将包含FormGroup
。
下一个,ngx-subformcomp
与[formControlName]='obj'
或[formControl]='obj'
提供的表单控件通信,需要implement control value accessor interface。一开始可能会很棘手。为了向前迈出更小的一步,您可能希望将ctr
权限传递给ngx-subformcomp
。
还有最大的一个? 乍一看,在控件之间分离管理表单部分的职责似乎总是一个好主意。就像一个组件管理数组一样,另一个组件管理项目。在实践中它变得痛苦。很快,逻辑就在几个组件中传播开来。很难理解表单控件之间的所有验证和依赖关系。根据我的经验,对于复杂的表单,管理一个包含所有验证、所有依赖项、所有结构和特定于该表单的助手的服务总是很容易。这样的服务也很容易被单元测试覆盖。组件仅用于显示数据并将用户输入绑定到 HTML 控件,仅此而已。使用这种方法可以更轻松地维护代码?
【讨论】:
以上是关于Angular 表单:如何动态添加/删除子表单组件的主要内容,如果未能解决你的问题,请参考以下文章