在以往动态处理 FormGroup 和 FormArray 嵌套表单时,通常要写一大堆的长长的形如这样的代码:
<form nz-form [formGroup]="form">
<div formArrayName="teacher">
<div nz-form-control *ngFor="let m of teachers.controls;index as isFirst" >
<div [formGroupName]="isFirst">
<input nz-input formControlName="name" />
<div *nz-explain="这里区了获取一个FormControl,需要写很长的代码,如:form.get('user.school.name')......">
error...
</div>
</div>
</div>
</div>
</div>
</form>
这其中多了一些乱七八糟的东西,如:formArrayName,formGroupName,formControlName,form.get(,...,)
,看到或写这样的代码感觉要晕死过去...
为了解决这样的问题,想出了下面的这个解决方案
解决方案
import { Directive, TemplateRef, Input, QueryList, ViewContainerRef, Component, ContentChildren } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
@Directive({
selector: '[ctrl]',
})
export class Ctrl {
constructor(public view: ViewContainerRef, public template: TemplateRef<any>) {}
}
@Component({
selector: 'group',
template: `<ng-content></ng-content>`
})
export class SeeFormGroupComponent {
@Input() group: FormGroup | FormControl | any;
@ContentChildren(Ctrl) ctrl: QueryList<Ctrl>;
get fields() {
if (this.group instanceof FormGroup) {
return this.group.controls;
}
if (this.group instanceof FormControl) {
return this.group;
}
return new FormControl(this.group);
}
ngAfterContentInit() {
if (this.group) {
const ctrls = this.ctrl.toArray();
setTimeout(()=>{
ctrls.forEach(r => {
r.view.createEmbeddedView(r.template, { $implicit: this.fields });
})
},0);
}
}
}
使用
<group *ngFor="let m of users.controls" [group]="m">
<div *ctrl="let user">
<input [formControl]="user.name" />
<input [formControl]="user.label" />
<div *ngIf="user.name.errors">
用户名不能为空!
</div>
</div>
</group>
终于不用看到,形如:formArrayName,formGroupName,formControlName,form.get(,...,)
这些乱七八糟的东西了
天之骄子 深圳 2018.12.26
网友评论