Łączenie strumienia z flatMap
Przypadki FlatMap:
- Prosty obserwowalny strumień
- Strumień - tablica
- Filtrowanie przedmiotów z każdego zdarzenia
- Strumień filtrowanych elementów
- Filtr + mapa uproszczona
Załóżmy, że chcemy zaimplementować funkcję wyszukiwania AJAX, w której każde naciśnięcie klawisza w polu tekstowym automatycznie wykona wyszukiwanie i zaktualizuje stronę z wynikami. Jak by to wyglądało? Cóż, mamy Observable
subskrybowane zdarzenia pochodzące z pola wejściowego, a przy każdej zmianie wejścia chcemy wykonać pewne żądanie HTTP, również Observable
, które subskrybujemy.
Używając flatMap
możemy przekształcić strumień zdarzeń (zdarzenia keypress w polu tekstowym) do naszego strumienia odpowiedzi (wyniki wyszukiwania z żądania HTTP).
app/services/search.service.ts
import { Http } from '@angular/http';
import { Injectable } from '@angular/core';
const SERVER = 'https://books.otwartaedukacja.pl/books';
@Injectable()
export class SearchService {
constructor(private http: Http) {}
search(term: string) {
return this.http.get(SERVER+`?title=${term}`)
.map(response => { return response.json(); });
}
}
Tutaj mamy podstawową usługę wyszukiwanie według podanego klucza. Funkcja search
zwracaObservable
, wykonując pewne podstawowe przetwarzanie (przekształca odpowiedź w obiekt JSON).
Komponent, który będzie korzystał z tej usługi:
app/app.component.ts
import { Component } from '@angular/core';
import { FormControl,
FormGroup,
FormBuilder } from '@angular/forms';
import { SearchService } from './services/search.service';
import 'rxjs/Rx';
@Component({
selector: 'app-root',
template: `
<form [formGroup]="coolForm">
<input formControlName="search" placeholder="Search book">
</form>
<div *ngFor="let book of result">
{{book.title}} [{{book.authors}}]
</div>
`
})
export class AppComponent {
searchField: FormControl;
coolForm: FormGroup;
result : any;
constructor(private searchService:SearchService, private fb:FormBuilder) {
this.searchField = new FormControl();
this.coolForm = fb.group({search: this.searchField});
this.searchField.valueChanges
.debounceTime(400)
.flatMap(term => this.searchService.search(term))
.subscribe(result => {
this.result = result;
});
}
}
Zobacz przykład [026]
Tutaj ustawiliśmy podstawowy formularz z pojedynczym polem, search
, którego zmiany obserwujemy. Metoda debounceTime wprowadza czas opóźnienia (400ms). Całą "magię" wykonuje flatMap
, który łączy dwa strumienie Observables
(z formularza i odczytu z serwera) w jeden spójny strumień. Strumień ten możemy wykorzystać do kontrolowania zdarzeń pochodzących z danych wprowadzanych przez użytkownika i odpowiedzi serwera.
Zauważ, że flatMap spłaszcza strumień zapytań do strumienia emitowanych wartości (prosteObservable
). Każde naciśnięcie klawisza w polu formularza powoduje natychmiastowe odświeżenie wyników!