Angular 5 Material Autocomplete多服务调用异常问题求助
解决Angular 5 Material Autocomplete多服务调用串数据的问题
嘿,我之前在做类似的多Autocomplete场景时也踩过这个坑!你遇到的所有自动补全框都显示同一个服务选项的问题,核心原因是多个组件共用了同一个过滤数据源或者模板引用变量,导致数据流串了。
问题根源分析
当你只用单个服务时,整个组件里的filteredOptions变量只对应一组数据,没问题;但添加多个服务后,如果:
- 所有Autocomplete都绑定到同一个
filteredOptionsObservable - 模板里的
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
相关产品推荐
相关产品推荐

