Angular 7 和表单数组错误无法找到带有路径的控件 [英] Angular 7 and form arrays error of cannot find a control with path
问题描述
我正在使用 mat-table
数据源构建一个包含数组的表单组.
我从创建表开始:
</td></ng-容器><ng-container matColumnDef="actual_date"><th mat-header-cell *matHeaderCellDef>实际日期<td mat-cell *matCellDef="let element; let i=index;"><div [formGroupName]="i"><mat-form-field color="warn" appearance="legacy"><mat-label>实际分布.日期</mat-label><input formControlName="actual_date" matInput [matDatepicker]="picker2" placeholder="实际日期"><mat-datepicker-toggle matSuffix [for]="picker2"></mat-datepicker-toggle><mat-datepicker #picker2></mat-datepicker></mat-form-field>
</td></ng-容器><ng-container matColumnDef="note"><th mat-header-cell *matHeaderCellDef>注意</th><td mat-cell *matCellDef="let element;let i=index;"><div [formGroupName]="i"><mat-form-field color="warn" appearance="legacy"><mat-label>注意</mat-label><input formControlName="note" matInput type="text" placeholder="Note"></mat-form-field>
</td></ng-容器><ng-container matColumnDef="actions"><th mat-header-cell *matHeaderCellDef>动作</th><td mat-cell *matCellDef="let element"><button mat-raised-button color="warn" type="submit" color="warn" (click)="addDist(element)"><mat-icon>add</mat-icon>添加按钮></td></ng-容器><tr mat-header-row *matHeaderRowDef="displayedColumns;sticky: true"></tr><tr mat-row *matRowDef="让行;列:displayColumns;"}"></tr></表单>
对于打字稿:
this.formGroup = this.fb.group({分布:this.fb.array([this.createArray()])});
和 createArray():
createArray(): FormGroup {返回 this.fb.group({'注意':new FormControl(''),'kit': new FormControl(''),'actual_date': new FormControl('')});
当用户上传文件时触发第一个打字稿:
之前上传文件的形式没有错误.
但是当我上传文件时,表单数组出现错误:
<块引用>错误:找不到路径控制:'分发 -> 1'在 _throwError (forms.js:1790)在 setUpFormContainer (forms.js:1772)在 FormGroupDirective.push
它指向:
<mat-form-field color="warn"外观="填充"><mat-label>试剂盒</mat-label><mat-select formControlName="kit" id="kit" placeholder="Kit"><mat-option *ngFor="let pk of projectKit" [value]="pk.project_kit">{{pk.kit_name}} 部分项目{{pk.project_name}}</mat-option></mat-select></mat-form-field>
编辑
添加{{formGroup.value|后JSON}}
我明白了:
{ "distribution": [ { "note": "", "kit": "", "actual_date": "" } ] }
问题是你的数据源,让 i=index 引用数据源的值,如果你的数组中的元素少于你的数据源中的元素,那么你的代码崩溃
如果表格中的所有元素都属于 FormArray,那就简单"了,您可以在 这个stackblitz
有两个键,
如何创建表单
myform:FormGroup=new FormGroup({分布:新 FormArray(ELEMENT_DATA.map(x=>{返回新的表单组({位置:新的FormControl(x.position),名称:新表单控件(x.name),重量:新的FormControl(x.weight),符号:新表单控件(x.symbol),})}))});
以及,我们如何引用控件
但是你有一个dataSource"和一个不连接的formArray.您可以创建一个函数来引用数组
get distributionArray(){返回 this.myForm.get('distribution') 作为 FormArray}
并在您的 td 中使用一些类似的内容
<input formControlName="name" ></td>}
好吧,不一定对所有人都有价值,但数组中的元素必须与数据源中的元素一样多,例如
this.myform:FormGroup=new FormGroup({分布:新的FormArray(ELEMENT_DATA.map(()=>{//只有两个属性为空返回新的表单组({重量:新的FormControl(),符号:新的FormControl(),})}))});
或者使用推送
this.myform:FormGroup=new FormGroup({分布:新的FormArray([])});ELEMENT_DATA.forEach(()=>{(this.myForm.get('distribution') as FormArray).push(this.createArray())}
I am building a form group with an array inside of it, using mat-table
data source.
I started by creating the table:
<form *ngIf="formGroup" [formGroup]="formGroup">
<table mat-table [dataSource]="dataSource" *ngIf="total>0" formArrayName="distribution">
<ng-container matColumnDef="ind_id">
<th mat-header-cell *matHeaderCellDef> ID </th>
<td mat-cell *matCellDef="let element">{{element.individual_id}}</td>
</ng-container>
<ng-container matColumnDef="ind_name">
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let element">{{element.ind_name}}</td>
</ng-container>
<ng-container matColumnDef="ind_status">
<th mat-header-cell *matHeaderCellDef> Ind. Status </th>
<td mat-cell *matCellDef="let element">{{element.ind_status}}</td>
</ng-container>
<ng-container matColumnDef="project_kit">
<th mat-header-cell *matHeaderCellDef> Kits </th>
<td mat-cell *matCellDef="let element; let i=index;">
<div [formGroupName]="i">
<mat-form-field color="warn" appearance="fill">
<mat-label>Kits</mat-label>
<mat-select formControlName="kit" id="kit" placeholder="Kit">
<mat-option *ngFor="let pk of projectKit" [value]="pk.project_kit">{{pk.kit_name}} part of project
{{pk.project_name}}</mat-option>
</mat-select>
</mat-form-field>
</div>
</td>
</ng-container>
<ng-container matColumnDef="actual_date">
<th mat-header-cell *matHeaderCellDef> Actual Date </th>
<td mat-cell *matCellDef="let element; let i=index;">
<div [formGroupName]="i">
<mat-form-field color="warn" appearance="legacy">
<mat-label>Actual Dist. Date</mat-label>
<input formControlName="actual_date" matInput [matDatepicker]="picker2" placeholder="Actual Date">
<mat-datepicker-toggle matSuffix [for]="picker2"></mat-datepicker-toggle>
<mat-datepicker #picker2></mat-datepicker>
</mat-form-field>
</div>
</td>
</ng-container>
<ng-container matColumnDef="note">
<th mat-header-cell *matHeaderCellDef> Note </th>
<td mat-cell *matCellDef="let element;let i=index;">
<div [formGroupName]="i">
<mat-form-field color="warn" appearance="legacy">
<mat-label>Note</mat-label>
<input formControlName="note" matInput type="text" placeholder="Note">
</mat-form-field>
</div>
</td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef> Actions </th>
<td mat-cell *matCellDef="let element">
<button mat-raised-button color="warn" type="submit" color="warn" (click)="addDist(element)">
<mat-icon>add</mat-icon> Add
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"
}"></tr>
</table>
</form>
And for the typescript:
this.formGroup = this.fb.group({
distribution: this.fb.array([
this.createArray()
])
});
And createArray():
createArray(): FormGroup {
return this.fb.group({
'note': new FormControl(''),
'kit': new FormControl(''),
'actual_date': new FormControl('')
});
The first typescript is fired when the user upload a file:
<form [formGroup]="uploadForm" role="form">
<input #fileInput type="file" formControlName="upload" value="Upload Excel/CSV file"
(change)="upload($event.target.files)" accept=".xlsx, .xls, .csv" />
<button mat-raised-button id="inputFile" color="accent" (click)="reset()">
<mat-icon color="warn">cancel</mat-icon>Reset
</button>
</form>
There is no error for the previous form of uploading a file.
But when I upload a file an error appears for the form array:
Error: Cannot find control with path: 'distribution -> 1'
at _throwError (forms.js:1790)
at setUpFormContainer (forms.js:1772)
at FormGroupDirective.push
And it's pointing on:
<div [formGroupName]="i">
<mat-form-field color="warn" appearance="fill">
<mat-label>Kits</mat-label>
<mat-select formControlName="kit" id="kit" placeholder="Kit">
<mat-option *ngFor="let pk of projectKit" [value]="pk.project_kit">{{pk.kit_name}} part of project
{{pk.project_name}}</mat-option>
</mat-select>
</mat-form-field>
</div>
EDIT
After Adding {{formGroup.value| JSON}}
I got this:
{ "distribution": [ { "note": "", "kit": "", "actual_date": "" } ] }
解决方案 the problem is your dataSource, let i=index make reference to the values of the dataSource, if you has less element in your array than in your dataSource your code crash
If all your elements in the table belongs to the FormArray it's "easy", you can see an example in this stackblitz
There are two keys,
one how create the Form
myform:FormGroup=new FormGroup({
distribution:new FormArray(ELEMENT_DATA.map(x=>{
return new FormGroup({
position:new FormControl(x.position),
name:new FormControl(x.name),
weight:new FormControl(x.weight),
symbol:new FormControl(x.symbol),
})}))
});
And, how We refereed to the controls
<form *ngIf="myform" [formGroup]="myform">
<ng-container formArrayName="distribution">
<!--see that datasource is myForm.get('distribution').controls-->
<table mat-table [dataSource]="myform.get('distribution').controls" class="mat-elevation-z8" >
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef> No. </th>
<!--so, "element" is a formGroup-->
<td mat-cell *matCellDef="let element;let i=index" [formGroup]="element"> <input formControlName="position" > </td>
</ng-container>
....
</table>
</ng-container>
</form>
But you has a "dataSource" and a formArray some disconected. You can create a function to referred to the array
get distributionArray()
{
return this.myForm.get('distribution') as FormArray
}
And use in your td some like
<td mat-cell *matCellDef="let element;let i=index"
[formGroup]="distributionArray.at(i)">
<input formControlName="name" >
</td>
}
well, it's not necesary has value to all, but must there are so many elements in the array as in the dataSource, e.g.
this.myform:FormGroup=new FormGroup({
distribution:new FormArray(ELEMENT_DATA.map(()=>{
//only two properties empty
return new FormGroup({
weight:new FormControl(),
symbol:new FormControl(),
})}))
});
Or using push
this.myform:FormGroup=new FormGroup({
distribution:new FormArray([])
});
ELEMENT_DATA.forEach(()=>{
(this.myForm.get('distribution') as FormArray).push(this.createArray())
}
这篇关于Angular 7 和表单数组错误无法找到带有路径的控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文
登录
关闭
扫码关注1秒登录
发送“验证码”获取
|
15天全站免登陆