You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Mat Autocomplete设置默认值:加载页面显示已保存预选值

解决Angular多mat-autocomplete组件预选值加载问题

你的核心问题在于所有行的autocomplete共用了同一个myControl FormControl,而且错误地试图修改mat-option的value来设置预选值——这完全搞错了方向:预选值应该绑定到输入框的FormControl上,而非选项列表。下面是具体的修复方案:

步骤1:为每个section创建独立的FormControl

在组件类中维护一个Map,用来存储每个课程章节对应的FormControl,确保每个autocomplete都有自己独立的状态:

import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
import { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';

@Component({
  // 组件元数据省略
})
export class YourComponent implements OnInit {
  // 假设这是你的课程列表
  courses: any[] = [];
  // 保存已选择的值的Map
  assigned: Map<string, string> = new Map();
  // 存储每个section对应的FormControl
  sectionControls: Map<string, FormControl> = new Map();
  // 所有可选的选项列表
  allOptions: string[] = ['Option 1', 'Option 2', 'Option 3']; // 替换成你的实际选项

  ngOnInit(): void {
    // 假设这里你已经从后端/本地存储获取了courses和assigned数据
    this.loadCoursesAndAssignedValues();

    // 为每个课程章节创建FormControl并设置初始值
    this.courses.forEach(course => {
      const initialValue = this.assigned.get(course.courseSection) || '';
      const control = new FormControl(initialValue);
      this.sectionControls.set(course.courseSection, control);
    });
  }

  // 为每个section提供独立的过滤逻辑
  getFilteredOptions(section: string): Observable<string[]> {
    const control = this.sectionControls.get(section);
    return control.valueChanges.pipe(
      startWith(control.value), // 初始值触发一次过滤
      map(value => this._filter(value))
    );
  }

  // 通用过滤方法
  private _filter(value: string): string[] {
    const filterValue = value.toLowerCase();
    return this.allOptions.filter(option => 
      option.toLowerCase().includes(filterValue)
    );
  }

  onSelectionChanged(section: string, event: MatAutocompleteSelectedEvent): void {
    this.assigned.set(section, event.option.value);
    // 这里可以添加保存逻辑(比如存到localStorage或后端)
  }

  private loadCoursesAndAssignedValues(): void {
    // 模拟加载数据的逻辑
    this.courses = [
      { courseSection: 'Math 101' },
      { courseSection: 'English 201' }
    ];
    this.assigned.set('Math 101', 'Option 2'); // 模拟已保存的值
  }
}

步骤2:修改HTML模板绑定独立的FormControl

把原来共用的myControl替换为当前章节对应的FormControl,并使用独立的过滤流:

<ng-container matColumnDef="course">
  <th mat-header-cell *matHeaderCellDef mat-sort-header> Course Section </th>
  <td mat-cell *matCellDef="let course"> 
    {{course.courseSection}} 
    <mat-form-field>
      <input type="text" 
             id="{{course.courseSection}}" 
             placeholder="Pick one" 
             aria-label="Number" 
             matInput 
             [formControl]="sectionControls.get(course.courseSection)" 
             [matAutocomplete]="auto">
      <mat-autocomplete #auto="matAutocomplete" (optionSelected)="onSelectionChanged(course.courseSection, $event)">
        <mat-option *ngFor="let option of getFilteredOptions(course.courseSection) | async" [value]="option">
          {{option}}
        </mat-option>
      </mat-autocomplete>
    </mat-form-field>
  </td>
</ng-container>

为什么原来的方法无效?

  1. 共用FormControl:所有autocomplete绑定同一个myControl会导致所有输入框状态同步,根本无法实现独立选择。
  2. 错误修改mat-option的value:mat-option是用来渲染可选列表的,修改它的value会让所有选项变成同一个值,完全不符合预期。正确的做法是给输入框的FormControl设置初始值,autocomplete会自动匹配对应的选项并显示。

内容的提问来源于stack exchange,提问作者a p

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:33:07