如何在异步httpclient调用中使用ngx-bootstrap typeahead

时间:2018-01-12 16:59:55

标签: javascript angular bootstrap-4 ngx-bootstrap

我正在尝试使用来自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">&#10060; 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)

但这不太正确

2 个答案:

答案 0 :(得分:4)

这是解决方案,它可能有一些写得不好或冗余的代码(尤其是.map(r => r)),它向我看来,也许它可以简化,但是用{{1来获得异步结果这将起作用:

HttpClient

答案 1 :(得分:1)

我这样做了:

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