2016-11-26 10 views
3

Ich arbeite an der Implementierung einer Suchfunktionalität über Angular2/TypeScript.Angular2 Observable bindet nicht korrekt

Ich habe Probleme beim Binden der Sucheinträge, die zur Ansicht zurückgegeben werden.

Meine Komponente ist dies:

import { Component } from '@angular/core'; 
import { SearchService } from '../services/search.service'; 
import { Observable } from 'rxjs/Observable'; 
import { Subject } from 'rxjs/Subject'; 
import "rxjs/add/operator/debounceTime"; 
import "rxjs/add/operator/distinctUntilChanged"; 
import 'rxjs/add/operator/switchMap'; 

@Component({ 
    selector: 'search', 
    templateUrl: './app/views/search.component.html', 
    providers: [SearchService] 
}) 

export class SearchComponent { 
    items: Observable<string[]>; 
    errorMsg: string; 

    private searchTermStream = new Subject<string>(); 

    searchConfluence(term : string) { 
    // Send the search term into the Observable stream 
    this.searchTermStream.next(term); 
    } 

    ngOnInit(): void { 
    this.items = this.searchTermStream 
     .debounceTime(300) 
     .distinctUntilChanged() 
     .switchMap(term => this.searchService.titleSearch(term)); 
    } 

    constructor(private searchService: SearchService) {} 
} 

Meine Ansicht ist die folgende:

<h1>Search</h1> 
<input #term (keyup)="searchConfluence(term.value)" /> 
<ul style="list-style: none"> 
    <li *ngFor="let item of items | async"> 
    {{item.title}} 
    </li> 
</ul> 

Mein Suchdienst:

import { Injectable } from '@angular/core'; 
import { Http, Response, Headers, RequestOptions } from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/catch'; 
import 'rxjs/add/observable/throw'; 

@Injectable() 
export class SearchService { 

    private searchUrl = URL_HERE; 

    constructor(private http: Http) {} 

    titleSearch(params: string): Observable<string[]> { 
    let options = new RequestOptions({ headers: this.header}); 
    let requestString = `term=${params}`; 
    return this.http.get(`${this.searchUrl}?${requestString}`, options) 
     .map(this.getData) 
     .catch(this.handleError); 
    } 

    private getData(resp: Response) { 
    let body = resp.json(); 
    console.log(body.results); 
    return body.results || []; 
    } 

    private handleError(error: Response | any) { 
    let errMsg: string; 
    if (error instanceof Response) { 
     const body = error.json() || ''; 
     const err = body.error || JSON.stringify(body); 
     errMsg = `${error.status} - ${error.statusText || ''} ${err}`; 
    } else { 
     errMsg = error.message ? error.message : error.toString(); 
    } 
    return Observable.throw(errMsg); 
    } 
} 

Die Antwort vom Server zurück folgt:

[Object, Object ... ] 

wobei jedes Object ein JSON-Objekt ist. Das erwarte ich als Antwort.

Ich habe die Netzwerk-Trace überprüft und die HTTP-Anfrage wird an den richtigen Ort ausgelöst und ich bekomme auch Ergebnisse zurück (wiederum alle über den Netzwerk-Trace angezeigt). Ich kann die Ergebnisse in meiner Ansicht nicht anzeigen (die Liste wird nicht angezeigt).

EDIT: Eine letzte Bearbeitung, aber ich habe vielleicht ein entscheidendes Detail weggelassen; Meine Angular2-Anwendung befindet sich nicht in einem typischen Browser, sondern ist in einer ElectronJS-Anwendung enthalten. Ich bin mir nicht sicher, ob das einen Unterschied macht.

+1

Könnten Sie bitte auch den Service-Code "SearchService" hinzufügen? –

+1

Code scheint perfekt, sollte es funktionieren .. möglicherweise etwas verwandte Daten aus der API abgerufen wird nicht richtig gebunden .. irgendein Fehler in der Konsole? –

+0

Bitte aktualisieren Antwortobjekt in Frage .. –

Antwort

0

Nach einem Tag nur herumspielen, bekam ich die Antwort auf diese Frage.

Es sieht so aus, als ob die API von Electron nicht so schnell aktualisiert wird wie ein Webbrowser. Daher habe ich die in here gefundene Lösung verwendet.

Im Grunde mache ich dies in meiner search.component.ts Klasse:

ngOnInit(): void { 
    this.searchTermStream 
    .debounceTime(300) 
    .distinctUntilChanged() 
    .switchMap(term => this.searchService.titleSearch(term)) 
    .subscribe((result) => { 
     this.items = result; 
     this.cdRef.detectChanges(); 
    }); 
    } 

Und voila, korrekt aktualisiert alles, und ich habe eine schöne Liste meiner Suchergebnisse :).

Verwandte Themen