Vat*_*ato 0 typescript angular angular-reactive-forms controlvalueaccessor
我试图使用CVA具有2个嵌套表单。问题是当我将第二个from绑定到formControl时没有用数据初始化。
我有主表格:
this.requestForm = this.fb.group({
garageId: 0,
routes: new FormArray([
new FormGroup({
addressPointId: new FormControl,
municipalityId: new FormControl,
regionId: new FormControl,
rvId: new FormControl,
sequenceNumber: new FormControl,
settlementId: new FormControl,
regionName: new FormControl,
municipalityName: new FormControl,
settlementName: new FormControl,
description: new FormControl,
})
]),
endDateTime: 0,
});
Run Code Online (Sandbox Code Playgroud)
在主要形式的html中,我使用formArrayName将路由绑定到。
<app-cva-form-array formArrayName="routes"></app-cva-form-array>
Run Code Online (Sandbox Code Playgroud)
组件CVA-FORM-ARRAY具有。
form = new FormArray([
new FormGroup({
addressPointId: new FormControl,
municipalityId: new FormControl,
regionId: new FormControl,
rvId: new FormControl,
sequenceNumber: new FormControl,
settlementId: new FormControl,
regionName: new FormControl,
municipalityName: new FormControl,
settlementName: new FormControl,
description: new FormControl,
})
]);
Run Code Online (Sandbox Code Playgroud)
从这里开始一切都很好。我将数组中的每个formGroup绑定到子组件CVA-FORM。
<app-cva-form [formControl]="route" (blur)="onTouched()"></app-cva-form>
Run Code Online (Sandbox Code Playgroud)
对于每个formGroup的CVA-FORM,我创建了单独的组件,以防万一我想使用组件本身而不是整个数组。
form: FormGroup = new FormGroup({
regionName: new FormControl,
regionId: new FormControl,
municipalityName: new FormControl,
municipalityId: new FormControl,
sequenceNumber: new FormControl,
settlementName: new FormControl,
settlementId: new FormControl,
addressPointId: new FormControl,
description: new FormControl,
rvId: new FormControl,
});
Run Code Online (Sandbox Code Playgroud)
主表单<-至-> app-cva-form-array绑定由于某些原因无法正常工作。
这些形式的思想来自kara关于angulaconnect的演讲。 这是她的幻灯片。
请帮助!
当您使用“自定义表单控件”时,需要考虑到您将cursom表单控件与表单控件(不是FormArray,不是FormGroup)一起提供了。FormControl具有一个数组或对象作为值,但是您不必对此感到困惑。(*)
您可以在stackblitz的工作中看到
那就是你的形式就像
//in main.form
this.requestForm = new FormGroup({
garageId: new FormControl(0),
routes: new FormControl(routes), //<--routes will be an array of object
endDateTime: new FormControl(0)
})
//in cva-form-array
this.form=new FormArray([new FormControl(...)]); //<-this.form is a
//formArray of FormControls NOT of formGroup
//finally in your cva-form
this.form=new FormGroup({});
this.form=formGroup({
addressPointId: new FormControl(),
municipalityId: new FormControl(),
...
})
Run Code Online (Sandbox Code Playgroud)
我创建了一个const以导出为简单的代码。我的const expor是
export const dataI = {
addressPointId: "",
municipalityId: "",
regionId: "",
rvId: "",
sequenceNumber: "",
settlementId: "",
regionName: "",
municipalityName: "",
settlementName: "",
description: "",
}
Run Code Online (Sandbox Code Playgroud)
因此,在mainForm中,我们有
ngOnInit() {
let routes:any[]=[];
routes.push({...dataI});
this.requestForm = new FormGroup({
garageId: new FormControl(0),
routes: new FormControl(routes),
endDateTime: new FormControl(0)
})
}
<mat-card [formGroup]="requestForm" style="background: #8E8D8A">
<app-cva-form-array formControlName="routes"></app-cva-form-array>
</mat-card>
Run Code Online (Sandbox Code Playgroud)
在cvc-form数组中,当我们赋值时创建formArray
writeValue(v: any) {
this.form=new FormArray([]);
for (let value of v)
this.form.push(new FormControl(value))
this.form.valueChanges.subscribe(res=>
{
if (this.onChange)
this.onChange(this.form.value)
})
}
<form [formGroup]="form" >
<mat-card *ngFor="let route of form.controls;
let routeIndex = index; let routeLast = last;">
<button (click)="deleteRoute(routeIndex)">
cancel
</button>
<app-cva-form [formControl]="route" (blur)="onTouched()"></app-cva-form>
</form>
Run Code Online (Sandbox Code Playgroud)
最后,CVA形式
writeValue(v: any) {
this.form=new FormGroup({});
Object.keys(dataI).forEach(x=>{
this.form.addControl(x,new FormControl())
})
this.form.setValue(v, { emitEvent: false });
this.form.valueChanges.subscribe(res=>{
if (this.onChanged)
this.onChanged(this.form.value)
})
}
<div [formGroup]="form">
<mat-form-field class="locationDate">
<input formControlName="regionName">
<mat-autocomplete #region="matAutocomplete"
(optionSelected)="selectedLocation($event)">
<mat-option *ngFor="let region of regions"
[value]="region">
{{region.regionName}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<mat-form-field class="locationDate">
<input formControlName="municipalityName"
[matAutocomplete]="municipality"
(blur)="onTouched()"
[readonly]="checked || this.form.value.regionId < 1">
....
</form>
Run Code Online (Sandbox Code Playgroud)
(*)是,我们习惯于看到FormControl具有字符串或数字作为值,但是没有人禁止我们将该值作为对象或数组(例如ng-bootstrap DatePicker存储对象{year :.. month:..,day ..},mat-multiselect存储数组,...)
更新当然,我们可以向控件提供来自服务或类似服务的数据。我们唯一需要考虑的就是我们如何提供数据。通常,我喜欢创建一个接收数据或null并返回FormControl的函数。
getForm(data: any): FormGroup {
data = data || {} as IData;
return new FormGroup({
garageId: new FormControl(data.garageId),
routes: new FormControl(data.routes),
endDateTime: new FormControl(data.endDateTime)
})
}
Run Code Online (Sandbox Code Playgroud)
IData是接口
export interface IData {
garageId: number;
routes: IDetail[];
endDateTime: any
}
Run Code Online (Sandbox Code Playgroud)
和IDetail另一个接口
export interface IDetail {
addressPointId: string;
...
description: string;
}
Run Code Online (Sandbox Code Playgroud)
然后我们可以得到一个复杂的数据,例如(大对象很抱歉)
let data = {
garageId: 1,
routes: [{
addressPointId: "adress",
municipalityId: "municipallyty",
regionId: "regionId",
rvId: "rvId",
sequenceNumber: "sequenceNumber",
settlementId: "settlementId",
regionName: "regionName",
municipalityName: "municipalityName",
settlementName: "settlementName",
description: "description",
},
{
addressPointId: "another adress",
municipalityId: "another municipallyty",
regionId: "another regionId",
rvId: "another rvId",
sequenceNumber: "another sequenceNumber",
settlementId: "another settlementId",
regionName: "another regionName",
municipalityName: "another municipalityName",
settlementName: "another settlementName",
description: "another description",
}],
endDateTime: new Date()
}
Run Code Online (Sandbox Code Playgroud)
然后只需要make
this.requestForm = this.getForm(data);
Run Code Online (Sandbox Code Playgroud)
堆栈闪电战(如果更新)
归档时间: |
|
查看次数: |
1168 次 |
最近记录: |