Angular FormArray选择下拉选项后自动填充关联文本框实现方法
Angular响应式表单FormArray下拉选择联动填充实现
1. HTML事件绑定问题修正
你当前写的(change)="update($event.target)"写法是错误的:
mat-select是Angular Material封装的组件,不支持原生change事件的$event.target直接获取控件实例,强行使用会抛出空值错误- 组件本身提供了官方的选择事件
selectionChange,不需要额外绑定原生change事件 - 你现有代码缺少FormArray的遍历逻辑,无法定位到当前操作行对应的FormGroup
修正后的HTML代码如下:
<ng-container [formGroup]="deliveryReceiptForm"> <div formArrayName="displayArray"> <!-- 遍历FormArray下的所有行控件,绑定当前行FormGroup --> <div *ngFor="let group of displayArray.controls; let i = index" [formGroupName]="i"> <td> <mat-select style="width:200px" class="form-control" formControlName="itemId" (selectionChange)="update(group)"> <mat-option *ngFor="let item of propertyItem" [value]="item.id"> {{item.propertyNo}} </mat-option> </mat-select> </td> <td> <input style="width:300px" class="form-control" type="text" formControlName="itemDescription"> </td> </div> </div> </ng-container>
2. TS层update方法实现
首先新增FormArray的getter方便模板访问,再实现联动填充逻辑:选中下拉选项后,根据选中的itemId从源数据propertyItem中匹配对应项,把描述字段填充到同组的itemDescription控件即可。
完整TS参考代码:
import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, FormArray, Validators } from '@angular/forms'; @Component({ selector: 'app-delivery-receipt', templateUrl: './delivery-receipt.component.html' }) export class DeliveryReceiptComponent implements OnInit { deliveryReceiptForm: FormGroup; // 下拉源数据,根据实际接口返回的字段名调整即可 propertyItem: Array<{id: number|string, propertyNo: string, description: string}> = []; constructor(private formBuilder: FormBuilder) {} ngOnInit(): void { this.deliveryReceiptForm = this.formBuilder.group({ displayArray : this.formBuilder.array([this.createList()]) }) } // 快捷获取displayArray FormArray实例,供模板调用 get displayArray(): FormArray { return this.deliveryReceiptForm.get('displayArray') as FormArray; } createList(): FormGroup { return this.formBuilder.group({ itemId : ['', Validators.required], itemDescription : ['', Validators.required] }) } // 联动更新逻辑 update(currentGroup: FormGroup): void { // 获取当前行选中的itemId const selectedId = currentGroup.get('itemId').value; // 从源数据中匹配id对应的完整项 const matchedItem = this.propertyItem.find(item => item.id === selectedId); if (matchedItem) { // 将匹配到的描述字段填充到当前行的itemDescription控件 // 如果你的源数据描述字段名不是description,替换成实际字段名即可 currentGroup.patchValue({ itemDescription: matchedItem.description }) } else { // 选中值为空时清空描述框 currentGroup.patchValue({ itemDescription: '' }) } } }
3. 实现注意事项
- 绑定
selectionChange事件时直接传入当前行的FormGroup实例,不需要传事件对象,定位控件更准确,不会出现跨行改值的问题 - 填充表单值优先使用
patchValue,不需要传入FormGroup下所有字段的值,仅更新指定字段即可,比setValue灵活性更高 - 如果需要新增行、删除行功能,只需调用FormArray的
push、removeAt方法即可,联动逻辑不需要额外调整
内容的提问来源于stack exchange,提问作者Yan
相关产品推荐
相关产品推荐

