2017-06-13 47 views
0

如何更改英雄搜索組件(https://angular.io/generated/live-examples/toh-pt6/eplnkr.html)的Angular 2 Tour of Heroes搜索組件(https://angular.io/generated/live-examples/toh-pt6/eplnkr.html),以便它將init上的所有項目(在頁面加載時顯示所有Heroes)過濾器提供它向服務獲取過濾結果到英雄變量的新請求?需要在用戶添加任何過濾器之前將所有項目加載到Observable <Hero[]>

import { Component, OnInit } from '@angular/core'; 
import { Router }   from '@angular/router'; 

import { Observable }  from 'rxjs/Observable'; 
import { Subject }   from 'rxjs/Subject'; 

// Observable class extensions 
import 'rxjs/add/observable/of'; 

// Observable operators 
import 'rxjs/add/operator/catch'; 
import 'rxjs/add/operator/debounceTime'; 
import 'rxjs/add/operator/distinctUntilChanged'; 

import { HeroSearchService } from './hero-search.service'; 
import { Hero } from './hero'; 

@Component({ 
    selector: 'hero-search', 
    templateUrl: './hero-search.component.html', 
    styleUrls: [ './hero-search.component.css' ], 
    providers: [HeroSearchService] 
}) 
export class HeroSearchComponent implements OnInit { 
    heroes: Observable<Hero[]>; 
    private searchTerms = new Subject<string>(); 

    constructor(
    private heroSearchService: HeroSearchService, 
    private router: Router) {} 

    // Push a search term into the observable stream. 
    search(term: string): void { 
    this.searchTerms.next(term); 
    } 

    ngOnInit(): void { 
    this.heroes = this.searchTerms 
     .debounceTime(300)  // wait 300ms after each keystroke before considering the term 
     .distinctUntilChanged() // ignore if next search term is same as previous 
     .switchMap(term => term // switch to new observable each time the term changes 
     // return the http search observable 
     ? this.heroSearchService.search(term) 
     // or the observable of empty heroes if there was no search term 
     : Observable.of<Hero[]>([])) 
     .catch(error => { 
     // TODO: add real error handling 
     console.log(error); 
     return Observable.of<Hero[]>([]); 
     }); 
    } 

    gotoDetail(hero: Hero): void { 
    let link = ['/detail', hero.id]; 
    this.router.navigate(link); 
    } 
} 

目前只是在提供搜索詞後發送請求。

+0

所以,你想看到所有的英雄,而不是**熱門英雄**,我纔得到這個權利還是我誤解你的問題? – codtex

+0

我不需要改變** Top Heroes **的行爲,我只需要在默認情況下顯示所有英雄列表,當輸入內容時,列表將被過濾。 –

+0

我試着給'this.search(「」);''ngOnInit()'內部添加一個調用,但似乎沒有任何事情發生(服務未執行)。 –

回答

1

Hello_

基本上這是你可以做的改變讓主的地方它的工作:

.switchMap(
    term => term  
    ? this.heroSearchService.search(term) 
    : Observable.of<Hero[]>([])) // <----- HERE if term is empty string you want to return all Heroes instead of empty collection 

實現這一點,你可以從hero.service.ts注入HeroService其中有方法getHeroes()這是返回所有的英雄。

所以現在我們可以改變上面的代碼看起來像這樣:

// First don't forget to inject HeroService and don't forget to import it too 
constructor(
    private heroSearchService: HeroSearchService, 
    private heroService: HeroService, 
    private router: Router) {} 

// Then the ngOnInit() will look like this 
ngOnInit(): void { 
    this.heroes = this.searchTerms 
     .debounceTime(300)   
     .distinctUntilChanged() 
     .switchMap(term => term 
     ? this.heroSearchService.search(term) 
     : this.heroService.getHeroes()) // <--- HERE if term is empty return all heroes 
     .catch(error => { 
     console.log(error); 
     return Observable.of<Hero[]>([]); 
     }); 

     // Wait for 100 ms before loading all heroes ... 
     setTimeout(() => { 
     this.search(''); 
     }, 100); 
} 

嗯,這是你的問題的解決方案和HERE你可以看到它在行動。

我試着添加一個調用this.search(「」);內部ngOnInit()

是的,我們需要這個加載所有的英雄,但給它一個小的延遲,否則什麼都沒有顯示。

讓我知道,如果一切都清楚了:)

+0

感謝您的回答。但是,我們沒有辦法在沒有setTimeout的情況下調用'search()'方法嗎? –

+1

這對我來說看起來像是一個計時問題,用setTimeout()調用它似乎很好。我現在想的其他事情是實現'AfterViewInit'並在'ngAfterViewInit()'內部調用'this.search('')',但是這沒有測試,你可以試試它並報告結果是什麼 – codtex

+0

看起來像一個更「優雅」的解決方案。謝謝 –

相關問題