2016-11-26 2 views
3

Я работаю над реализацией функции поиска через Angular2/TypeScript.Angular2 Observable not binding правильно

У меня возникли проблемы с привязкой элементов поиска, возвращенных на просмотр.

Мой компонент заключается в следующем:

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

Мое мнение заключается в следующем:

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

Мой сервис поиска:

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

Ответ, возвращаемый сервером заключается в следующем:

[Object, Object ... ] 

где каждый Object является объектом JSON. Это то, что я ожидаю в ответ.

Я проверил сетевую трассировку, и HTTP-запрос выстрелил в нужное место, и я снова получаю результаты (опять же, все просмотренные по сетевой трассе). Я не могу просмотреть какие-либо результаты в своем представлении (список просто не отображается).

EDIT: Последнее редактирование, но я, возможно, оставил критическую деталь; мое приложение Angular2 не находится в типичном браузере, но фактически содержится в приложении ElectronJS. Я не уверен, что это имеет значение.

+1

не могли бы вы также добавить служебный код SearchService? –

+1

Код кажется идеальным, он должен работать .. может быть, что-то связанное с данными, полученное из API, неправильно привязано .. любая ошибка в консоли? –

+0

, пожалуйста, обновите соответствующий объект ответа. –

ответ

0

После одного дня просто возиться, я получил ответ на этот вопрос.

Похоже, API-интерфейс Electron не обновляется так быстро, как это делает веб-браузер, поэтому я следовал решению, найденному в here.

В основном я делаю это в моем search.component.ts классе:

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

И вуаля, все правильно обновить, и у меня есть хороший список моих результатов поиска :).