Angular 5:table 中的动态表单验证
Angular 5: Dynamic Form Validation inside a table
我正在尝试使用表单组验证 table 中的输入字段,但无法实现。
我正在使用 *ngFor 来迭代数据,因为我必须在 table 的第一列中显示该数据,而其他列只是输入文本字段,我必须在其中添加表单验证。
所以我为字段的唯一表单控件名称添加了索引。
HTML代码
<form [formGroup]="tableForm">
<table class="shop-table table-responsive" cellspacing="0">
<tbody>
<tr class="cart_item" *ngFor="let data of final_selected_data; let i= index;">
<td class="product-thumbnail">
<a href="#"><img src="assets/images/nike.jpg" alt="" width="100"></a>
</td>
<td class="product-name">
<a href="#">{{data.size_ui}} ({{data.color_ui}}, {{data.material_ui}})</a> </td>
<td class="product-quantity" data-title="SKU">
<div class="quantity buttons_added">
<input step="1" value="" title="SKU" class="text" size="6" type="text" placeholder="SKU*" style="width:80px;" matInput [formControl]="tableForm.controls['variant_sku'+i]">
</div>
</td>
<td class="product-quantity" data-title="Price">
<div class="quantity buttons_added">
<input step="1" min="0" max="" value="" title="Price" class="text" size="6" type="number" placeholder="Price*" style="width:80px;" matInput [formControl]="tableForm.controls['variant_price'+i]">
</div>
</td>
<td class="product-remove">
<a href="#" class="remove" title="Remove this item"><mat-icon>delete</mat-icon></a>
</td>
</tr>
</tbody>
</table>
</form>
Component.ts
ngOnInit() {
for(let i = 0; i < this.final_selected_data.length; i++){
var j = (i).toString();
let variant_sku = 'variant_sku'+j;
let variant_price = 'variant_price'+j;
let variant_stock = 'variant_stock'+j;
let variant_moq = 'variant_moq'+j;
this.tableForm = this.fb.group({
variant_sku: [null, Validators.compose([Validators.required])],
variant_price: [null, Validators.compose([Validators.required])]
});
}
}
错误
ERROR Error: Cannot find control with unspecified name attribute
您现在所做的只是在您的表单中创建 2 个表单控件,无论您的数组长度如何。你需要的是一个 FormArray
,你可以为数组中的每个对象推送新的表单组......所以一个缩短的版本是:
this.tableForm = this.fb.group({
arr: this.fb.array([])
})
let arr = this.tableForm.get('arr') as FormArray;
for (let i = 0; i < this.final_selected_data.length; i++) {
arr.push(this.fb.group({
variant_sku: [this.final_selected_data[i].variant_sku, [Validators.required]]
}))
}
然后在您的模板中迭代您的格式数组:
<form [formGroup]="tableForm">
<table>
<tbody formArrayName="arr">
<tr *ngFor="let a of this.tableForm.get('arr')['controls']; let i= index;">
<td class="product-quantity" [formGroupName]="i">
<input formControlName="variant_sku">
<!-- not pretty, but just for demonstration! -->
<p *ngIf="a.hasError('required', 'variant_sku')">Required!</p>
</td>
</tr>
</tbody>
</table>
</form>
演示:https://stackblitz.com/edit/angular-vcjjfr?file=src%2Fapp%2Fapp.component.html
我正在尝试使用表单组验证 table 中的输入字段,但无法实现。 我正在使用 *ngFor 来迭代数据,因为我必须在 table 的第一列中显示该数据,而其他列只是输入文本字段,我必须在其中添加表单验证。 所以我为字段的唯一表单控件名称添加了索引。
HTML代码
<form [formGroup]="tableForm">
<table class="shop-table table-responsive" cellspacing="0">
<tbody>
<tr class="cart_item" *ngFor="let data of final_selected_data; let i= index;">
<td class="product-thumbnail">
<a href="#"><img src="assets/images/nike.jpg" alt="" width="100"></a>
</td>
<td class="product-name">
<a href="#">{{data.size_ui}} ({{data.color_ui}}, {{data.material_ui}})</a> </td>
<td class="product-quantity" data-title="SKU">
<div class="quantity buttons_added">
<input step="1" value="" title="SKU" class="text" size="6" type="text" placeholder="SKU*" style="width:80px;" matInput [formControl]="tableForm.controls['variant_sku'+i]">
</div>
</td>
<td class="product-quantity" data-title="Price">
<div class="quantity buttons_added">
<input step="1" min="0" max="" value="" title="Price" class="text" size="6" type="number" placeholder="Price*" style="width:80px;" matInput [formControl]="tableForm.controls['variant_price'+i]">
</div>
</td>
<td class="product-remove">
<a href="#" class="remove" title="Remove this item"><mat-icon>delete</mat-icon></a>
</td>
</tr>
</tbody>
</table>
</form>
Component.ts
ngOnInit() {
for(let i = 0; i < this.final_selected_data.length; i++){
var j = (i).toString();
let variant_sku = 'variant_sku'+j;
let variant_price = 'variant_price'+j;
let variant_stock = 'variant_stock'+j;
let variant_moq = 'variant_moq'+j;
this.tableForm = this.fb.group({
variant_sku: [null, Validators.compose([Validators.required])],
variant_price: [null, Validators.compose([Validators.required])]
});
}
}
错误
ERROR Error: Cannot find control with unspecified name attribute
您现在所做的只是在您的表单中创建 2 个表单控件,无论您的数组长度如何。你需要的是一个 FormArray
,你可以为数组中的每个对象推送新的表单组......所以一个缩短的版本是:
this.tableForm = this.fb.group({
arr: this.fb.array([])
})
let arr = this.tableForm.get('arr') as FormArray;
for (let i = 0; i < this.final_selected_data.length; i++) {
arr.push(this.fb.group({
variant_sku: [this.final_selected_data[i].variant_sku, [Validators.required]]
}))
}
然后在您的模板中迭代您的格式数组:
<form [formGroup]="tableForm">
<table>
<tbody formArrayName="arr">
<tr *ngFor="let a of this.tableForm.get('arr')['controls']; let i= index;">
<td class="product-quantity" [formGroupName]="i">
<input formControlName="variant_sku">
<!-- not pretty, but just for demonstration! -->
<p *ngIf="a.hasError('required', 'variant_sku')">Required!</p>
</td>
</tr>
</tbody>
</table>
</form>
演示:https://stackblitz.com/edit/angular-vcjjfr?file=src%2Fapp%2Fapp.component.html