2017-07-30 121 views
2

我正在關注Angular教程來構建一個簡單的應用程序。當我在輸入框中輸入術語時,應用程序會發送一個Ajax來搜索用戶。我在這裏與Observable混淆。Angular Observable錯誤處理

(1)如果搜索詞短於3個單詞,我想清除數據。我使用Observable.of來返回一個空數組。

(2)如果發生http錯誤,一個空數組也會在catch塊中返回。

然而,在這兩種情況之一後,似乎流'停止',因爲我指向this.users到一個新的Observable。我是否應該再次執行類似this.users = new Subject()的操作?在這裏做什麼正確的方法?

HTML:

<div class="wrapper"> 
    <input #searchBox id="search-box" (keyup)="search(searchBox.value)" /> 
    <div class="loader" [hidden]="!loading"></div> 
</div> 

getUserService:

//Sending ajax, return an Observable 

組件:在正確的地方

export class searchComponent implements OnInit { 

    constructor(private getUserService: GetUserService) { } 

    private searchTerms = new Subject<string>(); 

    users: Observable<User[]>; 
    loading: boolean = false; 

    search(term: string): void { 
     if(term.length >= 3) { 
      this.loading = true; 
      this.searchTerms.next(term); 
     } else { 

      //issue (1) occurs after this 

      this.users = Observable.of<User[]>([]); 
     } 
    } 

    ngOnInit(): void { 
    this.users = this.searchTerms 
     .debounceTime(400) 
     .distinctUntilChanged() 
     //service will not be called after (1) or (2) occurs 
     .switchMap(term => this.getUserService.getUser(term)) 
      .map(data => { 
       this.loading = false; 
       return data; 
      }) 
     .catch(error => { 

     //issue (2) occurs after this 

     this.loading = false; 
     return Observable.of<User[]>([]); 
     }); 
    } 
} 

回答

3

你沒有做的事情。它應該是

search(term: string) { 
    // emit systematically. The observable chain will just return 
    // 0 result if the term is too short 
    this.searchTerms.next(term); 
} 

ngOnInit() { 
    this.users = this.searchTerms 
     .debounceTime(400) 
     .distinctUntilChanged() 
     .switchMap(term => { 
     if (term.length < 3) { 
      return Observable.of([]); 
     } 
     else { 
      this.loading = true; 
      return this.getUserService.getUser(term) 
        // catch here to make sure that an http error doesn't break the chain 
        .catch(() => return Observable.of([]) 
        .finally(() => this.loading = false); 
     } 
     }); 
}