[英]How to use ngx-bootstrap typeahead with async httpclient call
我正在嘗試使用來自Angular 4中的休息后端的異步結果填充nxg-bootstrap typeahead。他們的站點有一個示例( https://valor-software.com/ngx-bootstrap/#/typeahead )如何執行此操作使用模擬可觀察數據,但我正在努力使用httpclient。 使用它的人的所有示例都使用舊的Http
模塊而不是Angular 4中使用的新HttpClient
模塊。
這是他們的例子:
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { TypeaheadMatch } from 'ngx-bootstrap/typeahead';
@Component({
selector: 'demo-typeahead-async',
templateUrl: './async.html'
})
export class DemoTypeaheadAsyncComponent {
asyncSelected: string;
typeaheadLoading: boolean;
typeaheadNoResults: boolean;
dataSource: Observable<any>;
statesComplex: any[] = [
{ id: 1, name: 'Alabama', region: 'South' },
{ id: 2, name: 'Alaska', region: 'West' },
{
id: 3,
name: 'Arizona',
region: 'West'
},
{ id: 4, name: 'Arkansas', region: 'South' },
{ id: 5, name: 'California', region: 'West' },
{ id: 6, name: 'Colorado', region: 'West' },
{ id: 7, name: 'Connecticut', region: 'Northeast' },
{ id: 8, name: 'Delaware', region: 'South' },
{ id: 9, name: 'Florida', region: 'South' },
{ id: 10, name: 'Georgia', region: 'South' },
{ id: 11, name: 'Hawaii', region: 'West' },
{ id: 12, name: 'Idaho', region: 'West' },
{ id: 13, name: 'Illinois', region: 'Midwest' },
{ id: 14, name: 'Indiana', region: 'Midwest' },
{ id: 15, name: 'Iowa', region: 'Midwest' },
{ id: 16, name: 'Kansas', region: 'Midwest' },
{ id: 17, name: 'Kentucky', region: 'South' },
{ id: 18, name: 'Louisiana', region: 'South' },
{ id: 19, name: 'Maine', region: 'Northeast' },
{ id: 21, name: 'Maryland', region: 'South' },
{ id: 22, name: 'Massachusetts', region: 'Northeast' },
{ id: 23, name: 'Michigan', region: 'Midwest' },
{ id: 24, name: 'Minnesota', region: 'Midwest' },
{ id: 25, name: 'Mississippi', region: 'South' },
{ id: 26, name: 'Missouri', region: 'Midwest' },
{ id: 27, name: 'Montana', region: 'West' },
{ id: 28, name: 'Nebraska', region: 'Midwest' },
{ id: 29, name: 'Nevada', region: 'West' },
{ id: 30, name: 'New Hampshire', region: 'Northeast' },
{ id: 31, name: 'New Jersey', region: 'Northeast' },
{ id: 32, name: 'New Mexico', region: 'West' },
{ id: 33, name: 'New York', region: 'Northeast' },
{ id: 34, name: 'North Dakota', region: 'Midwest' },
{ id: 35, name: 'North Carolina', region: 'South' },
{ id: 36, name: 'Ohio', region: 'Midwest' },
{ id: 37, name: 'Oklahoma', region: 'South' },
{ id: 38, name: 'Oregon', region: 'West' },
{ id: 39, name: 'Pennsylvania', region: 'Northeast' },
{ id: 40, name: 'Rhode Island', region: 'Northeast' },
{ id: 41, name: 'South Carolina', region: 'South' },
{ id: 42, name: 'South Dakota', region: 'Midwest' },
{ id: 43, name: 'Tennessee', region: 'South' },
{ id: 44, name: 'Texas', region: 'South' },
{ id: 45, name: 'Utah', region: 'West' },
{ id: 46, name: 'Vermont', region: 'Northeast' },
{ id: 47, name: 'Virginia', region: 'South' },
{ id: 48, name: 'Washington', region: 'South' },
{ id: 49, name: 'West Virginia', region: 'South' },
{ id: 50, name: 'Wisconsin', region: 'Midwest' },
{ id: 51, name: 'Wyoming', region: 'West' }
];
constructor() {
this.dataSource = Observable.create((observer: any) => {
// Runs on every search
observer.next(this.asyncSelected);
}).mergeMap((token: string) => this.getStatesAsObservable(token));
}
getStatesAsObservable(token: string): Observable<any> {
let query = new RegExp(token, 'ig');
return Observable.of(
this.statesComplex.filter((state: any) => {
return query.test(state.name);
})
);
}
changeTypeaheadLoading(e: boolean): void {
this.typeaheadLoading = e;
}
changeTypeaheadNoResults(e: boolean): void {
this.typeaheadNoResults = e;
}
typeaheadOnSelect(e: TypeaheadMatch): void {
console.log('Selected value: ', e.value);
}
}
用模板
<pre class="card card-block card-header">Model: {{asyncSelected | json}}
</pre>
<input [(ngModel)]="asyncSelected"
[typeahead]="dataSource"
(typeaheadLoading)="changeTypeaheadLoading($event)"
(typeaheadNoResults)="changeTypeaheadNoResults($event)"
(typeaheadOnSelect)="typeaheadOnSelect($event)"
[typeaheadOptionsLimit]="7"
typeaheadOptionField="name"
placeholder="Locations loaded with timeout"
class="form-control">
<div *ngIf="typeaheadLoading===true">Loading</div>
<div *ngIf="typeaheadNoResults===true">❌ No Results Found</div>
這是我嘗試的唯一一個無法工作的部分:
this.dataSource = Observable.create((observer: any) => {
// Runs on every search
observer.next(this.typeAheadResult);
}).mergeMap((token: string) => {
return this.httpClient.get<string[]>(`${this.typeAheadUrl}?q=${token}`);
});
通常情況下,對於這樣的通話,我會做類似的事情:
this.httpClient.get<string[]>(`${this.typeAheadUrl}?q=${token}`)
.subscribe(results => this.results = results)
但這不太正確
這是解決方案,它可能有一些寫得不好或冗余的代碼(尤其是.map(r => r)
),它向我看,也許它可以簡化,但是用HttpClient
獲取異步結果,這個將工作:
this.dataSource = Observable.create((observer: any) => {
// Runs on every search
observer.next(this.typeAheadResult);
}).mergeMap((token: string) => {
return this.httpClient.get<string[]>(`${this.typeAheadUrl}?q=${token}`).map(r => r);
});
我這樣做了:
this.dataSource = Observable.create((observer: Observer<any[]>) => {
this.httpClient.get<string[]>(`${this.typeAheadUrl}?q=${token}`).subscribe((responseItems: any[]) => {
observer.next(responseItems);
});
});
這是有效的,如果您必須檢查某些條件是否已滿,以發送請求,這很有趣,例如,檢查輸入字段是否已被聚焦。 如果您不需要做任何類似的事情,這更簡單:
this.dataSource = this.httpClient.get<string[]>(`${this.typeAheadUrl}?q=${token}`);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.