2017-05-16 3 views
1

Ich möchte ngBootstrap für Angular 4 Typeahead für Autocomplete verwenden. Das Beispiel, das sie für den Remote-Datenabruf verwenden, verwendet Jsonp und nicht http. Ich habe versucht, mehr Informationen zu finden, um Jsonp mit http in diesem Beispiel zu ersetzen. Ich bin mit Observablen noch nicht so vertraut, also versuche ich sie zu lernen und verstehe sie besser.Verwenden von http mit ngBootstrap TypeAhead für Angular 4

Ich habe diese example gesehen, aber es sieht wirklich einfach und vielleicht (?) Lässt viel ... aus Gründen der Einfachheit aus?

Kann jemand in die richtige Richtung zeigen, ich versuche, einige gute Beispiele mit http mit ngBootstrap Typeahead zu finden.

bearbeiten

{ 
    "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" 
     } 
     }, 

bearbeiten 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

Ich glaube, ich habe mir zu arbeiten, aber ich bin ein nicht genau, wie ich es tat. Ich habe das Beispiel verwendet, das du hier gepostet hast! –

Antwort

2

Ich glaube, ich weiß, ein wenig darüber, wie es zu erklären. Ich baue jedoch ein Modal, das Filter behandelt. Unten ist mein httpService. getCarriers, die eine Suchzeichenfolge verwendet.

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

In meinem modal Komponente (filters.component.ts) Datei, zu wissen, dass mein Dienst eine Reihe von Objekten zurückgibt, ich hatte eine Formatierers Verfahren zu schaffen, sowohl die Eingabe als auch die Ergebnisse Objekt zu handhaben Strukturen.

Ich dachte, dass, da der ngbdTypeahead ein Observable akzeptiert, ich den Begriff zu meinem httpservice senden und es einem Observable zurückgeben würde, anstatt zu versuchen, es zu abonnieren.

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

} 

Hier ist mein HTML-Template für mein modal:

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

Lassen Sie mich wissen, ob es irgendwelche spezifischen Fragen sind. Ich hackte herum, bis ich es funktionierte.

Unnötig zu sagen, obwohl debounceTime genial ist, möchte ich immer noch keine Anfrage ausführen, bis der Benutzer mindestens 3 Zeichen eingegeben hat. Ich erhalte einen Fehler, wenn ich versuche, diese Logik in der switchMap zu platzieren.

enter image description here

+0

kam jetzt zurück, musste sich um einige Dinge kümmern. Kannst du deine Formatiererfunktion ein bisschen mehr erklären. Ich habe den gleichen Deal, den Sie tun, mein Service gibt eine Reihe von Objekten zurück, ich benutze Elasticsearch. – user3125823

+0

formatter function expression nimmt jedes Objekt, mit dem es dargestellt wird, aus der dynamischen Anfrage und drillt auf die vorhandene Eigenschaft herunter, die gerendert werden soll. Was ist das Problem, das Sie mit Elasticsearch haben? Welche Art von Datendarstellung wird zurückgegeben? –

+0

Ich habe oben eine Bearbeitung mit einem ES-Retoursample hinzugefügt, das ich erhalte. Ich bin mir nur nicht sicher, wie man auf den Textwert von "Vorschlägen" drillt. – user3125823

Verwandte Themen