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

Angular 5 Material Autocomplete多服务调用异常问题求助

解决Angular 5 Material Autocomplete多服务调用串数据的问题

嘿,我之前在做类似的多Autocomplete场景时也踩过这个坑!你遇到的所有自动补全框都显示同一个服务选项的问题,核心原因是多个组件共用了同一个过滤数据源或者模板引用变量,导致数据流串了。

问题根源分析

当你只用单个服务时,整个组件里的filteredOptions变量只对应一组数据,没问题;但添加多个服务后,如果:

  • 所有Autocomplete都绑定到同一个filteredOptions Observable
  • 模板里的mat-autocomplete引用变量重复(比如都用#auto="matAutocomplete")
  • 过滤逻辑没有区分不同的表单控件,导致每次输入都会触发所有服务的请求并覆盖数据源

就会出现你说的“产品框显示供应商选项”这类串数据的情况。

具体解决方案

1. 为每个Autocomplete创建独立的过滤数据源

在组件类里,给每个服务对应的自动补全框单独定义Observable变量:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { Observable } from 'rxjs';
import { startWith, switchMap } from 'rxjs/operators';
import { ProductService } from './product.service';
import { SupplierService } from './supplier.service';
// 导入第三个服务,比如CustomerService

@Component({
  selector: 'app-autocomplete-demo',
  templateUrl: './autocomplete-demo.component.html'
})
export class AutocompleteDemoComponent implements OnInit {
  myForm: FormGroup;
  // 每个服务对应独立的过滤数据源
  filteredProducts$: Observable<any[]>;
  filteredSuppliers$: Observable<any[]>;
  filteredCustomers$: Observable<any[]>; // 第三个服务的数据源

  constructor(
    private fb: FormBuilder,
    private productService: ProductService,
    private supplierService: SupplierService,
    // 注入第三个服务
  ) {}

  ngOnInit(): void {
    this.myForm = this.fb.group({
      Id_Product: [''],
      Id_Supplier: [''],
      Id_Customer: [''] // 第三个表单控件
    });

    // 产品输入框的数据流处理
    this.filteredProducts$ = this.myForm.get('Id_Product').valueChanges.pipe(
      startWith(''), // 初始值为空,触发第一次加载
      switchMap(searchTerm => this.productService.getProducts(searchTerm))
    );

    // 供应商输入框的数据流处理
    this.filteredSuppliers$ = this.myForm.get('Id_Supplier').valueChanges.pipe(
      startWith(''),
      switchMap(searchTerm => this.supplierService.getSuppliers(searchTerm))
    );

    // 第三个服务的数据流处理
    this.filteredCustomers$ = this.myForm.get('Id_Customer').valueChanges.pipe(
      startWith(''),
      switchMap(searchTerm => this.customerService.getCustomers(searchTerm))
    );
  }
}

2. 模板中为每个Autocomplete绑定独立的数据源和引用变量

确保每个mat-autocomplete有唯一的模板引用变量,并且*ngFor循环对应正确的数据源:

<!-- 产品自动补全框 -->
<div class="example-container">
  <mat-form-field>
    <input 
      matInput 
      formControlName="Id_Product" 
      placeholder="Producto" 
      class="form-control" 
      id="Id_Product"
      [matAutocomplete]="productAuto"
    >
    <mat-autocomplete #productAuto="matAutocomplete">
      <mat-option 
        *ngFor="let product of filteredProducts$ | async" 
        [value]="product.Id_Product"
      >
        {{product.ProductName}}
      </mat-option>
    </mat-autocomplete>
  </mat-form-field>
</div>

<!-- 供应商自动补全框 -->
<div class="example-container">
  <mat-form-field>
    <input 
      matInput 
      formControlName="Id_Supplier" 
      placeholder="Proveedor" 
      class="form-control" 
      id="Id_Supplier"
      [matAutocomplete]="supplierAuto"
    >
    <mat-autocomplete #supplierAuto="matAutocomplete">
      <mat-option 
        *ngFor="let supplier of filteredSuppliers$ | async" 
        [value]="supplier.Id_Supplier"
      >
        {{supplier.SupplierName}}
      </mat-option>
    </mat-autocomplete>
  </mat-form-field>
</div>

<!-- 第三个自动补全框(比如客户) -->
<div class="example-container">
  <mat-form-field>
    <input 
      matInput 
      formControlName="Id_Customer" 
      placeholder="Cliente" 
      class="form-control" 
      id="Id_Customer"
      [matAutocomplete]="customerAuto"
    >
    <mat-autocomplete #customerAuto="matAutocomplete">
      <mat-option 
        *ngFor="let customer of filteredCustomers$ | async" 
        [value]="customer.Id_Customer"
      >
        {{customer.CustomerName}}
      </mat-option>
    </mat-autocomplete>
  </mat-form-field>
</div>

额外注意事项

  • 确保每个服务的搜索方法(比如getProducts、getSuppliers)是独立的,返回各自的Observable,不会互相干扰
  • 表单控件的formControlName必须和FormGroup中定义的键完全一致
  • 避免在模板中重复使用同一个mat-autocomplete引用变量(比如都用#auto),每个框的引用变量要唯一

内容的提问来源于stack exchange,提问作者Sergio Lopez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:49:04