我希望在Main窗体中能够动态添加/删除子窗体。子表单基于模型对象,并嵌入了几件事:
然后我为此子表单创建一个专用组件:
型号:
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() {
}
以及我的template:
<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 ...谢谢您的帮助
我在这里看到很多困惑(:
首先,这不是您可以迭代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控件,仅此而已。使用这种方法可以更轻松地维护代码😊