Angular页面刷新后,多选mat-select如何恢复之前选中的选项?
解决FormArray中多选mat-select刷新后无法恢复选中值的问题
核心问题在于多选mat-select绑定的是FormArray,刷新恢复表单时,不仅要还原表单数据,还要保证先加载依赖选项,再初始化选中值,以下是具体实现步骤:
1. 完善表单数据的保存与读取逻辑
先把表单数据持久化到localStorage(也可根据需求用其他存储方式),刷新后读取并重构表单:
// 组件初始化时加载保存的数据 ngOnInit() { this.form = this.loadForm(); this.loadSavedFormData(); } // 读取本地存储的表单数据并重构FormArray loadSavedFormData() { const savedData = localStorage.getItem('formData'); if (savedData) { const parsedData = JSON.parse(savedData); this.rebuildFormArray(parsedData.parentForm); } } // 保存表单数据(可在表单变更或组件销毁时调用) saveFormData() { localStorage.setItem('formData', JSON.stringify(this.form.value)); } ngOnDestroy() { this.saveFormData(); }
2. 重构FormArray时处理依赖与选中值
因为第二个下拉的选项依赖第一个下拉的选中值,所以重构时要按顺序处理:先设置第一个下拉的值,再加载对应选项,最后初始化多选下拉的选中值:
// 维护每个表单组对应的第二个下拉选项列表 field2OptionsList: any[][] = []; // 重构FormArray核心逻辑 rebuildFormArray(savedGroups: any[]) { const formArray = this.arrayOfForms(); this.field2OptionsList = []; // 清空旧的选项列表 savedGroups.forEach(group => { // 创建新的表单组 const newGroup = this.form(); // 设置第一个下拉的选中值 newGroup.get('field1')?.setValue(group.field1); // 根据第一个下拉的值加载第二个下拉的选项(替换成你实际的选项加载逻辑) const field2Options = this.loadField2Options(group.field1); this.field2OptionsList.push(field2Options); // 初始化多选下拉的选中值:逐个添加FormControl到field2的FormArray const field2Array = newGroup.get('field2') as FormArray; group.field2.forEach(selectedValue => { // 校验选中值是否在当前选项中,避免无效值 if (field2Options.some(opt => opt.value === selectedValue)) { field2Array.push(new FormControl(selectedValue)); } }); // 将重构好的表单组添加到父FormArray formArray.push(newGroup); }); } // 替换成你实际的选项加载方法,比如从接口获取或本地映射 loadField2Options(field1Value: string): any[] { // 示例:根据field1的值返回对应选项 const optionMap = { 'optionA': [{value: 'a1', label: '选项A1'}, {value: 'a2', label: '选项A2'}], 'optionB': [{value: 'b1', label: '选项B1'}, {value: 'b2', label: '选项B2'}] }; return optionMap[field1Value] || []; }
3. 模板与动态选项的绑定
确保模板中mat-select的绑定正确,并且动态关联选项列表:
<!-- 遍历FormArray中的每个表单组 --> <div *ngFor="let group of arrayOfForms().controls; let i = index" [formGroup]="group"> <!-- 第一个单选下拉 --> <mat-select formControlName="field1" (selectionChange)="onField1Change($event, i)"> <mat-option value="optionA">选项A</mat-option> <mat-option value="optionB">选项B</mat-option> </mat-select> <!-- 第二个多选下拉 --> <mat-select formControlName="field2" multiple> <mat-option *ngFor="let opt of field2OptionsList[i]" [value]="opt.value"> {{opt.label}} </mat-option> </mat-select> </div> <!-- 添加表单组按钮 --> <button (click)="addForm()">添加表单</button>
同时补充addForm和selectionChange的逻辑:
addForm() { const newGroup = this.form(); this.arrayOfForms().push(newGroup); // 初始化新表单组的第二个下拉选项 this.field2OptionsList.push([]); } // 第一个下拉值变化时,更新对应表单组的第二个下拉选项 onField1Change(event: any, index: number) { const field1Value = event.value; this.field2OptionsList[index] = this.loadField2Options(field1Value); // 清空当前多选下拉的选中值(可选,根据业务需求调整) const field2Array = (this.arrayOfForms().at(index).get('field2') as FormArray); while (field2Array.length) { field2Array.removeAt(0); } }
关键注意点
- 多选
mat-select绑定的是FormArray,不能直接用patchValue批量赋值,必须逐个添加FormControl。 - 必须先加载依赖选项,再设置选中值,否则
mat-select会忽略不在选项列表中的值。 - 保存表单数据时,确保
field2的选中值是可序列化的基础类型(如字符串、数字),避免存储对象导致解析异常。
内容的提问来源于stack exchange,提问作者Lorenz
相关产品推荐
相关产品推荐

