Observable(관찰 가능 개체)
12606 단어 Angular2
하나.배경의 Observable는 이벤트 흐름입니다. 우리는 그룹 조작부호로 그를 처리할 수 있습니다.Angular 커널은 관찰 가능한 대상에 대한 기본적인 지원을 제공합니다. 우리는 RxJS 대상에서 조작부호와 확장자를 도입할 수 있습니다.우리는 보통 Observable 뒤에 toPromise를 연결합니다. 이 조작부호는 Observable를promise로 변환하고promise를 호출자에게 되돌려줍니다.프로미스로 전환하는 것이 보통 더 좋은 선택입니다. 우리는 http를 요구합니다.get은 단일 블록 데이터를 가져옵니다. 데이터만 받으면 완성됩니다. 프로미스 같은 형식의 결과를 사용하면 호출이 쉽게 작성됩니다.그러나 요청은 항상 일회성이 아니다. 우리는 요청을 시작하고 취소할 수 있다. 서버가 첫 번째 요청에 응답하기 전에 다른 요청을 시작한다. 이런 요청-취소-새로운 요청은promise에 대해 실현하기 어렵지만 Observable에 대해서는 쉽다.
둘.이름별 검색은 사용자가 검색 상자에 이름을 입력할 때 http 요청을 끊임없이 해서 이름별로 필터를 하는 영웅을 얻을 것입니다.
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs';
import { Hero } from './hero';
@Injectable()
export class HeroSearchService {
constructor(private http: Http) {}
search(term: string): Observable {
return this.http
.get(`app/heroes/?name=${term}`)
.map((r: Response) => r.json().data as Hero[]);
}
}
셋.HeroSearchComponent
<div id="search-component">
<h4>Hero Searchh4>
<input #searchBox id="search-box" (keyup)="search(searchBox.value)" />
<div>
<div *ngFor="let hero of heroes | async"
(click)="gotoDetail(hero)" class="search-result" >
{{hero.name}}
div>
div>
div>
Heroes는 현재 영웅 목록의 Observable 대상이지 영웅 그룹이 아니기 때문에 *ngFor는 Observable로 어떤 일도 할 수 없습니다. 그의 뒤에 async pipe를 추가하지 않으면.이 async는 이 Observable에 구독하고,ngFor에 영웅 그룹을 생성합니다.
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { HeroSearchService } from './hero-search.service';
import { Hero } from './hero';
@Component({
moduleId: module.id,
selector: 'hero-search',
templateUrl: 'hero-search.component.html',
styleUrls: [ 'hero-search.component.css' ],
providers: [HeroSearchService]
})
export class HeroSearchComponent implements OnInit {
heroes: Observable;
private searchTerms = new Subject();
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 for 300ms pause in events
.distinctUntilChanged() // ignore if next search term is same as previous
.switchMap(term => term // switch to new observable each time
// return the http search observable
? this.heroSearchService.search(term)
// or the observable of empty heroes if no search term
: Observable.of([]))
.catch(error => {
// TODO: real error handling
console.log(error);
return Observable.of([]);
});
}
gotoDetail(hero: Hero): void {
let link = ['/detail', hero.id];
this.router.navigate(link);
}
}
넷.검색어 잘 보세요. 검색어 잘 보세요.
private searchTerms = new Subject<string>();
// Push a search term into the observable stream.
search(term: string): void {
this.searchTerms.next(term);
}
ject는 관찰할 수 있는 이벤트 흐름의 생산자입니다. 검색 Terms는 문자열을 생성하는 Observable를 생성하여 이름으로 검색할 때 필터 조건으로 사용합니다.
검색을 호출할 때마다next를 호출해서 이 테마의 관찰 가능한 흐름에 새 문자열을 넣습니다.
오.Heroes 속성 초기화subject도 Observable 대상입니다. 검색어의 흐름을 Hero 그룹의 흐름으로 바꾸고 결과를 Heroes 속성에 부여합니다.
heroes: Observable;
ngOnInit(): void {
this.heroes = this.searchTerms
.debounceTime(300) // wait for 300ms pause in events
.distinctUntilChanged() // ignore if next search term is same as previous
.switchMap(term => term // switch to new observable each time
// return the http search observable
? this.heroSearchService.search(term)
// or the observable of empty heroes if no search term
: Observable.of([]))
.catch(error => {
// TODO: real error handling
console.log(error);
return Observable.of([]);
});
}
만약 우리가 모든 사용자 버튼을 Hero Search 서비스에 직접 전송한다면 HTTP 요청 폭풍이 일어날 것입니다. 그러나 우리는 문자열 Observable 뒤에 Observable 조작부호를 연결해서 이 요청들을 합칠 수 있습니다.HeroSearch Service에 대해 더 적은 호출을 시작하고 충분한 대응을 얻을 것입니다. (1) 최종 문자열이 전송되기 전에 debounce (300) 는 새 문자열의 이벤트가 300밀리초 동안 중단될 때까지 기다릴 것입니다. (2) distinctUntilChange는 필터 조건만 바뀌어야 요청을 보낼 수 있습니다. (3) switchMap은 debounce와distinctUntilChage에서 통과한 검색어에 대한 검색 서비스를 호출합니다.그는 관찰할 수 있는 이전의 검색을 취소하고 버릴 것이며, 가장 가까운 것만 보류할 것이다.
switchMap 조작부호는 매우 지능적이다.조건에 맞는 버튼 이벤트마다 http 방법에 대한 호출을 터치합니다.모든 요청을 보내는 데 300밀리초의 지연이 있어도, 우리는 여전히 도중에 있는 http 요청을 동시에 가지고 있을 수 있으며, 이전의 호출이 취소되거나 버려졌기 때문에, 최근의 http 호출이 되돌아오는 관찰 대상만 되돌아갈 수 있다.만약 검색 상자가 비어 있다면, 우리는 이번 http 방법 호출을 단락으로 하고, 빈 그룹을 포함하는 관찰 가능한 대상을 직접 되돌릴 수 있습니다.주의: Herosearch 서비스의 관찰 대상을 취소하는 것은 서비스가 이 기능을 지원하지 않는 한 미완성 http 요청을 종료하지 않습니다.
RxJS 조작부호 가져오기 Angular의 기본 Observable 구현에서 RxJS 조작부호는 사용할 수 없습니다. Observable를 확장하기 위해 가져와야 합니다.이 파일의 맨 위에 import 문장을 쓰면 Observable에서 사용할 조작부호를 확장할 수 있습니다.다른 방법도 쓸 수 있어요.
// Observable class extensions
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/throw';
// Observable operators
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
그런 다음 최상위 AppModule에서 파일을 한 번에 가져옵니다.
import './rxjs-extensions';