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}`);