2017-05-16 105 views
1

我想使用ngBootstrap for Angular 4 Typeahead来自动完成。他们用于远程数据检索的例子是使用Jsonp而不是http。在这个例子中,我一直试图找到一些更多的信息来取代Jsonp。我对Observables还不是很熟悉,所以我正在努力学习它们并更好地理解它们。使用http with ngBootstrap Typeahead for Angular 4

我已经看到这个example,但它看起来真的简单,也许(?)留下了很多......为了简单起见?

有人可以指向正确的方向,我试图找到一些使用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); 
} 
+0

我想我有我的工作,但我是个不知道我究竟是怎么做到的。我用你在这里发布的例子! –

回答

2

我想我知道一点点怎么解释。但是,我正在构建一个处理滤镜的模式。以下是我的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); 
} 

以我模态分量(filters.component.ts)文件,知道我的服务返回对象的数组,我必须创建一个格式化方法来处理两个输入以及结果对象结构。

我觉得既然ngbdTypeahead接受了一个Observable,我会把这个词发给我的httpservice,并允许它返回一个Observable,而不是试图订阅它。

// 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() { 
    } 

} 

这里是我的我的模态HTML模板:

// 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> 

让我知道,如果有任何具体问题。我有点被黑了,直到我得到它的工作。不用说,即使debounceTime真棒,我仍然不想执行请求,直到用户键入至少3个字符。如果我尝试在switchMap中放置该逻辑,我会得到一个错误。

enter image description here

+0

现在回来了,不得不照顾一些事情。你能解释一下你的格式化函数吗?我有同样的交易,我的服务返回一个对象数组,我使用Elasticsearch。 – user3125823

+0

格式化函数表达式将从动态请求中提取出来的每个对象,并向下钻取到现有属性进行渲染。 Elasticsearch有什么问题?什么样的数据表示被返回? –

+0

我已经添加了一个我收到的ES返回样本的编辑。我只是不确定如何深入到“建议”的文本值。 – user3125823