将http与ngBootstrap Typeahead一起用于Angular 4

将http与ngBootstrap Typeahead一起用于Angular 4,angular,angular-ui-typeahead,Angular,Angular Ui Typeahead,我想使用ngBootstrap为Angular 4 Typeahead自动完成。他们的远程数据检索示例是使用Jsonp而不是http。在那个例子中,我一直试图找到更多的信息来用http替换Jsonp。我还不太熟悉可见光,所以我正在努力学习它们,更好地理解它们 我见过这个,但它看起来很简单,也许(?)漏掉了很多。。。为了简单起见 如果有人能指出正确的方向,我正试图找到一些使用http和ngBootstrap Typeahead的好例子 编辑 { "took": 15, "timed

我想使用ngBootstrap为Angular 4 Typeahead自动完成。他们的远程数据检索示例是使用Jsonp而不是http。在那个例子中,我一直试图找到更多的信息来用http替换Jsonp。我还不太熟悉可见光,所以我正在努力学习它们,更好地理解它们

我见过这个,但它看起来很简单,也许(?)漏掉了很多。。。为了简单起见

如果有人能指出正确的方向,我正试图找到一些使用http和ngBootstrap Typeahead的好例子

编辑

    {
  "took": 15,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0
  },
  "hits": {
    "total": 9,
    "max_score": 4.2456956,
    "hits": [
      {
        "_index": "query-index",
        "_type": "autocomplete",
        "_id": "AVxqBE-3t2o4jx2g0ntb",
        "_score": 4.2456956,
        "_source": {
          "suggestions": "bruce"
        }
      },
      {
        "_index": "query-index",
        "_type": "autocomplete",
        "_id": "AVxqBE-3t2o4jx2g0ntc",
        "_score": 3.064434,
        "_source": {
          "suggestions": "bruce wayne"
        }
      },
      {
        "_index": "query-index",
        "_type": "autocomplete",
        "_id": "AVxqBE-3t2o4jx2g0ntd",
        "_score": 3.064434,
        "_source": {
          "suggestions": "bruce willis"
        }
      },
编辑2

export class AutocompleteComponent {
  model: any;
  searching = false;
  searchFailed = false;

  constructor(private autocompleteService: Elasticsearch) {}

  //formatMatches = (query: any) => query.hits.hits._source.suggestions || '';
  //formatMatches = (query: any) => query.hits.hits || '';
  formatMatches = (query: any) => <any>response.json().hits.hits || '';
  search = (text$: Observable<string>) =>
  //search = (text$: Observable<Suggestion[]>) =>
    text$
      .debounceTime(300)
      .distinctUntilChanged()
      //.switchMap(term =>
      //Observable.fromPromise(this.autocompleteService.search(term)
      .switchMap(term =>
      this.autocompleteService.search(term)
      .do( () => this.searchFailed = false)
      .catch( () => {
        this.searchFailed = true;
        return Observable.of([]);
      }))
      .do( () => this.searching = false);
}
导出类自动完成组件{
型号:任意;
搜索=假;
searchFailed=false;
构造函数(私有自动完成服务:Elasticsearch){}
//formatMatches=(query:any)=>query.hits.hits._source.suggestions | |“”;
//formatMatches=(query:any)=>query.hits.hits | |“”;
formatMatches=(query:any)=>response.json().hits.hits | |“”;
搜索=(文本$:可观察)=>
//搜索=(文本$:可观察)=>
正文$
.debounceTime(300)
.distinctUntilChanged()
//.switchMap(术语=>
//Observable.fromPromise(this.autocompleteService.search(术语)
.switchMap(术语=>
this.autocompleteService.search(术语)
.do(()=>this.searchFailed=false)
.catch(()=>{
this.searchFailed=true;
([])的可观测收益率;
}))
.do(()=>this.search=false);
}

我想我知道一点如何解释它。但是,我正在构建一个处理过滤器的模式。下面是我的httpService。getCarriers它接受一个搜索字符串

getCarriers(query: string): Observable<any> {
  return this._http.get(this._ripcord + '/carriers?search_string=' + query, this.options)
    .map((response: Response) => <any>response.json().data)
    .do(data => console.log(data))
    .catch(this.handleError);
}

getCarriers(查询:字符串):Observable

我想我的工作已经开始了,但我不确定我到底是怎么做到的。我使用了你在这里发布的示例!现在回到这里,我必须处理一些事情。你能再解释一下你的格式化程序功能吗?我和你做的一样,我的服务返回一个对象数组,我使用Elasticsearch.formatter函数表达式n是从动态请求中获取它所呈现的每个对象,并向下钻取到要呈现的现有属性。Elasticsearch有什么问题?返回的数据表示形式是什么?我在上面添加了一个编辑,并收到一个ES返回示例。我只是不确定如何向下钻取到的文本值“建议”。您的对象有点复杂。您的组件看起来像什么?您在我的组件上看不到的是,我的Http请求创建了清理可观察对象的第一步。在您的情况下,您可能需要在我的示例response.json().data中返回data.hits.hits;而我认为您应该使用response.json().hits.hits
// filters.component.ts
import { Component, OnInit } from '@angular/core';
import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';

import { HttpService } from '../../../shared/http.service';
import { Carrier } from '../../../definitions/carrier';

@Component({
  selector: 'afn-ngbd-modal-content',
  templateUrl: './modal/filters.modal.html',
  styleUrls: ['./modal/filters.modal.css']
})
export class NgbdModalContentComponent {

  filtersForm: FormGroup;
  carriers: Carrier[];

  constructor(public activeModal: NgbActiveModal, public httpService: HttpService, private fb: FormBuilder) {
    this.createForm();
  }

  carrier_search = (text$: Observable<string>) =>
    text$
      .debounceTime(200)
      .distinctUntilChanged()
      .do((text) => console.log(text))
      .switchMap(term =>
        this.httpService.getCarriers(term)
      )
  ;

  formatter = (x: {attributes: {name: string}}) => x.attributes.name;

  createForm() {
    this.filtersForm = this.fb.group({
      name: ['', Validators.required],
    });
  }
}

@Component({
  selector: 'afn-filters',
  templateUrl: './filters.component.html',
  styleUrls: ['./filters.component.css']
})
export class FiltersComponent implements OnInit {

  constructor(private modalService: NgbModal) { }

  open() {
    const modalRef = this.modalService.open(NgbdModalContentComponent);
  }
  ngOnInit() {
  }

}
// filters.modal.html
<div class="modal-header">
  <h4 class="modal-title">Hi there!</h4>
  <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
    <span aria-hidden="true">&times;</span>
  </button>
</div>
<div class="modal-body">
  <!--<p>Hello, {{name}}!</p>-->
  <form [formGroup]="filtersForm" novalidate>
    <div class="form-group">
      <label class="center-block">Carrier:
        <input type="text" class="form-control" formControlName="name" [ngbTypeahead]="carrier_search" [inputFormatter]="formatter" [resultFormatter]="formatter">
      </label>
    </div>
  </form>

  <p>Form value: {{ filtersForm.value | json }}</p>
  <p>Form status: {{ filtersForm.status | json }}</p>
</div>
<div class="modal-footer">
  <button type="button" class="btn btn-secondary" (click)="activeModal.close('Close click')">Close</button>
</div>