如何基于对象数据源实现Angular Material Autocomplete组件?
解决Angular Material Autocomplete绑定对象数据源的类型错误问题
你的核心问题是嵌套订阅导致的类型不匹配,以及对象数据源未正确转换为Autocomplete所需的可遍历结构。以下是分步修复方案:
1. 修正数据源与过滤逻辑(组件类)
不要在map里直接订阅currencies$,这会返回Subscription而非预期的Observable。改用combineLatest结合表单值变化与数据源,同时将对象转换为可遍历数组:
import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; import { Observable, combineLatest, startWith, map } from 'rxjs'; import { CurrencyService } from './currency.service'; interface Currencies { currency: Record<string, string>; // 匹配你的currencies.json结构:{ currency: { USD: "US Dollar", ... } } } @Component({ selector: 'app-autocomplete-example', templateUrl: './autocomplete-example.component.html', }) export class AutocompleteExampleComponent implements OnInit { formMain: FormGroup; currencies$: Observable<Currencies>; filteredCurrencies$: Observable<{ key: string; value: string }[]>; constructor( private fb: FormBuilder, private _currencyService: CurrencyService ) { this.formMain = this.fb.group({ currency: [''] }); this.currencies$ = this._currencyService.list(); } ngOnInit(): void { // 组合表单输入变化与数据源,生成实时过滤的货币列表 this.filteredCurrencies$ = combineLatest([ this.formMain.get('currency')!.valueChanges.pipe(startWith('')), this.currencies$ ]).pipe( map(([inputValue, currencies]) => { const filterValue = inputValue.toString().toUpperCase(); // 将currency对象转为键值对数组后过滤 return Object.entries(currencies.currency) .map(([key, value]) => ({ key, value })) .filter(item => item.key.toUpperCase().includes(filterValue)); }) ); } }
2. 修正模板绑定
直接使用过滤后的filteredCurrencies$,无需keyvalue管道,确保async管道正确处理Observable:
<mat-form-field appearance="fill"> <mat-label>Currency</mat-label> <input id="currency" type="text" matInput placeholder="Select a currency. E.g. USD" [matAutocomplete]="auto" formControlName="currency" > <mat-autocomplete autoActiveFirstOption #auto="matAutocomplete"> <mat-option *ngFor="let currency of filteredCurrencies$ | async" [value]="currency.key" > {{ currency.key }} ({{ currency.value }}) </mat-option> </mat-autocomplete> </mat-form-field>
错误原因说明
你之前的代码中,map函数返回的是this.currencies$.subscribe(...)的结果(即Subscription对象),但currencies$的类型是Observable<Currencies>,这直接导致了TypeScript类型不匹配错误。通过combineLatest同时监听表单输入和数据源,既避免了嵌套订阅,也正确处理了类型转换。
内容的提问来源于stack exchange,提问作者xRay
相关产品推荐
相关产品推荐

