使用itemTemplate与Observable时ngx-bootstrap Typeahead显示[object Object]求助
解决方案:ngx-bootstrap Typeahead选中复杂对象显示"[object Object]"的问题
核心原因
当Typeahead绑定复杂对象数组时,组件默认会调用对象的toString()方法,导致输入框显示[object Object];同时你的代码中asyncSelected被定义为string类型,与实际绑定的对象类型不匹配,进一步加剧了这个问题。
具体解决方法
方法1:用typeaheadField指定显示字段
在input标签上添加[typeaheadField]="'name'",明确告诉组件使用对象的name属性作为输入框的显示值:
修改后的app.component.html:
<pre class="card card-block card-header mb-3">Model: {{ asyncSelected | json}}</pre> <input [(ngModel)]="asyncSelected" [typeahead]="dataSource" [typeaheadAsync]="true" [typeaheadItemTemplate]="customItemTemplate" [typeaheadField]="'name'" <!-- 添加此行 --> class="form-control"> <ng-template #customItemTemplate let-model="item" let-index="index"> <h5>This is: {{model | json}} Index: {{ index }}</h5> </ng-template>
方法2:自定义显示格式化函数(typeaheadFormatter)
如果需要更灵活的显示逻辑,可以自定义格式化函数:
- 在
app.component.ts中添加格式化函数:
formatSelectedState(state: any): string { return state ? `${state.name} (${state.region})` : ''; }
- 在html中绑定该函数:
<input [(ngModel)]="asyncSelected" [typeahead]="dataSource" [typeaheadAsync]="true" [typeaheadItemTemplate]="customItemTemplate" [typeaheadFormatter]="formatSelectedState" <!-- 添加此行 --> class="form-control">
方法3:修正变量类型
将asyncSelected的类型从string改为对应对象类型,避免类型不匹配问题:
// app.component.ts export class AppComponent { asyncSelected?: { id: number; name: string; region: string }; // 改为对象类型 // 其余代码不变 }
综合优化后的完整代码示例
app.component.ts
import { Component } from '@angular/core'; import { Observable, of, Subscriber } from 'rxjs'; import { mergeMap } from 'rxjs/operators'; export interface State { id: number; name: string; region: string; } @Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent { asyncSelected?: State; dataSource: Observable<State[]>; statesComplex: State[] = [ { id: 1, name: 'Alabama', region: 'South' }, { id: 2, name: 'Alaska', region: 'West' } ]; constructor() { this.dataSource = new Observable((observer: Subscriber<State | undefined>) => { observer.next(this.asyncSelected); }) .pipe( mergeMap((selectedState) => this.getStatesAsObservable(selectedState?.name || '')) ); } getStatesAsObservable(token: string): Observable<State[]> { const query = new RegExp(token, 'i'); return of( this.statesComplex.filter((state) => query.test(state.name)) ); } // 可选:自定义格式化函数 formatSelectedState(state: State): string { return state ? `${state.name} - ${state.region}` : ''; } }
app.component.html
<pre class="card card-block card-header mb-3">Model: {{ asyncSelected | json}}</pre> <input [(ngModel)]="asyncSelected" [typeahead]="dataSource" [typeaheadAsync]="true" [typeaheadItemTemplate]="customItemTemplate" [typeaheadField]="'name'" <!-- 若使用自定义格式化则替换为:[typeaheadFormatter]="formatSelectedState" --> class="form-control"> <ng-template #customItemTemplate let-model="item" let-index="index"> <h5>This is: {{model.name}} ({{model.region}}) Index: {{ index }}</h5> </ng-template>
内容的提问来源于stack exchange,提问作者A Jar of Clay
相关产品推荐
相关产品推荐

