parent
705a5d9e93
commit
8960b6729f
|
@ -25,7 +25,7 @@
|
||||||
"rxjs": "5.0.0-beta.0",
|
"rxjs": "5.0.0-beta.0",
|
||||||
"zone.js": "0.5.10",
|
"zone.js": "0.5.10",
|
||||||
|
|
||||||
"a2-in-memory-web-api": "^0.1.0",
|
"a2-in-memory-web-api": "^0.1.1",
|
||||||
"bootstrap": "^3.3.6"
|
"bootstrap": "^3.3.6"
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
// #docregion
|
// #docregion
|
||||||
import {Component} from 'angular2/core';
|
import {Component} from 'angular2/core';
|
||||||
import {JSONP_PROVIDERS} from 'angular2/http';
|
import {JSONP_PROVIDERS} from 'angular2/http';
|
||||||
import {Observable} from 'rxjs/Observable';
|
import {Observable} from 'rxjs/Observable';
|
||||||
// #docregion import-subject
|
// #docregion import-observer
|
||||||
import {Subject} from 'rxjs/Subject';
|
import {Observer} from 'rxjs/Observer';
|
||||||
// #enddocregion import-subject
|
// #enddocregion import-observer
|
||||||
|
|
||||||
import {WikipediaService} from './wikipedia.service';
|
import {WikipediaService} from './wikipedia.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -25,19 +26,21 @@ export class WikiSmartComponent {
|
||||||
|
|
||||||
constructor (private _wikipediaService: WikipediaService) { }
|
constructor (private _wikipediaService: WikipediaService) { }
|
||||||
|
|
||||||
// #docregion subject
|
search: (value: string) => void;
|
||||||
private _searchTermStream = new Subject();
|
|
||||||
|
|
||||||
search(value: string){
|
// #docregion observable-create
|
||||||
this._searchTermStream.next(value);
|
private _searchTermStream: Observable<string> =
|
||||||
}
|
Observable.create(
|
||||||
// #enddocregion subject
|
// #docregion subscribe-fn
|
||||||
|
(observer:Observer<string>) => this.search = (term) => observer.next(term)
|
||||||
|
// #enddocregion subscribe-fn
|
||||||
|
);
|
||||||
|
// #enddocregion observable-create
|
||||||
|
|
||||||
// #docregion observable
|
// #docregion observable-operators
|
||||||
items = this._searchTermStream
|
items:Observable<string[]> = this._searchTermStream
|
||||||
.debounceTime(300)
|
.debounceTime(300)
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.switchMap((term:string) => this._wikipediaService.search(term));
|
.switchMap((term:string) => this._wikipediaService.search(term));
|
||||||
|
// #enddocregion observable-operators
|
||||||
// #enddocregion observable
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import {Component} from 'angular2/core';
|
import {Component} from 'angular2/core';
|
||||||
import {JSONP_PROVIDERS} from 'angular2/http';
|
import {JSONP_PROVIDERS} from 'angular2/http';
|
||||||
import {Observable} from 'rxjs/Observable';
|
import {Observable} from 'rxjs/Observable';
|
||||||
|
|
||||||
import {WikipediaService} from './wikipedia.service';
|
import {WikipediaService} from './wikipedia.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|
|
@ -49,8 +49,8 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"server-communication": {
|
"server-communication": {
|
||||||
"title": "Server Communication",
|
"title": "Http Client",
|
||||||
"intro": "Learn to build applications that talk to a server."
|
"intro": "Talk to a remote server with the Angular Http Client."
|
||||||
},
|
},
|
||||||
|
|
||||||
"lifecycle-hooks": {
|
"lifecycle-hooks": {
|
||||||
|
|
|
@ -491,17 +491,32 @@ figure.image-display
|
||||||
+makeExample('server-communication/ts/app/wiki/wiki-smart.component.ts', null, 'app/wiki/wiki-smart.component.ts')
|
+makeExample('server-communication/ts/app/wiki/wiki-smart.component.ts', null, 'app/wiki/wiki-smart.component.ts')
|
||||||
:marked
|
:marked
|
||||||
We made no changes to the template or metadata, confining them all to the component class.
|
We made no changes to the template or metadata, confining them all to the component class.
|
||||||
|
Let's review those changes.
|
||||||
|
|
||||||
The first step turns the user's search box entries into the *subject* of an observable.
|
### Create the search term Observable
|
||||||
We import the `Subject` class from the RxJS observable library:
|
|
||||||
+makeExample('server-communication/ts/app/wiki/wiki-smart.component.ts', 'import-subject')
|
We import the `Observer` symbol from the RxJS observable library to get the type information:
|
||||||
|
+makeExample('server-communication/ts/app/wiki/wiki-smart.component.ts', 'import-observer')
|
||||||
:marked
|
:marked
|
||||||
After every keystroke we pump the search box value into the private `_searchTermStream` subject, creating a stream of search term strings.
|
The first real step turns the user's search box entries into an observable stream of search terms.
|
||||||
+makeExample('server-communication/ts/app/wiki/wiki-smart.component.ts', 'subject')(format='.')
|
We create a private `Observable` called `_searchTermStream`, driven by a *subscribe* function that
|
||||||
|
feeds user search terms to the observable.
|
||||||
|
|
||||||
|
+makeExample('server-communication/ts/app/wiki/wiki-smart.component.ts', 'observable-create')(format='.')
|
||||||
:marked
|
:marked
|
||||||
|
The *subscribe* function sets the component's `search` method to a function that updates
|
||||||
|
the observable's `observer` with search terms.
|
||||||
|
+makeExample('server-communication/ts/app/wiki/wiki-smart.component.ts', 'subscribe-fn')(format='.')
|
||||||
|
:marked
|
||||||
|
The search box `keyup` events are still bound to this `search` method in the template.
|
||||||
|
After every keystroke the binding pumps the search box value into the `_searchTermStream` observable,
|
||||||
|
creating a stream of search term strings.
|
||||||
|
|
||||||
|
### Listen for search terms
|
||||||
|
|
||||||
Earlier, we passed each search term directly to the service and bound the template to the service results.
|
Earlier, we passed each search term directly to the service and bound the template to the service results.
|
||||||
Now we listen to the *stream of terms*, manipulating the stream before it reaches the `WikipediaService`.
|
Now we listen to the *stream of terms*, manipulating the stream before it reaches the `WikipediaService`.
|
||||||
+makeExample('server-communication/ts/app/wiki/wiki-smart.component.ts', 'observable')(format='.')
|
+makeExample('server-communication/ts/app/wiki/wiki-smart.component.ts', 'observable-operators')(format='.')
|
||||||
:marked
|
:marked
|
||||||
We wait for the user to stop typing for at least 300 milliseconds
|
We wait for the user to stop typing for at least 300 milliseconds
|
||||||
([debounce](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/debounce.md)).
|
([debounce](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/debounce.md)).
|
||||||
|
@ -509,14 +524,15 @@ figure.image-display
|
||||||
([distinctUntilChanged](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/distinctuntilchanged.md)).
|
([distinctUntilChanged](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/distinctuntilchanged.md)).
|
||||||
|
|
||||||
The `WikipediaService` returns a separate observable of strings (`Observable<string[]>`) for each request.
|
The `WikipediaService` returns a separate observable of strings (`Observable<string[]>`) for each request.
|
||||||
We could have multiple requests "in flight", all awaiting the server's reply,
|
We could have multiple requests *in flight*, all awaiting the server's reply,
|
||||||
which means multiple *observables-of-strings* could arrive at any moment in any order.
|
which means multiple *observables-of-strings* could arrive at any moment in any order.
|
||||||
|
|
||||||
We rely on [switchMap](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/flatmaplatest.md)
|
The [switchMap](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/flatmaplatest.md)
|
||||||
(formerly known as `flatMapLatest`) to re-arrange these observables in their original-request order.
|
(formerly known as `flatMapLatest`) returns a new observable that combines these `WikipediaService` observables,
|
||||||
|
re-arranges them in their original request order,
|
||||||
The `switchmap` operator ensures that the component's `items` property is always set to the truly latest `WikipediaService` observable.
|
and delivers to subscribers only the most recent search results.
|
||||||
Consequently, the displayed list of search results stays in sync with the user's sequence of search terms.
|
|
||||||
|
The displayed list of search results stays in sync with the user's sequence of search terms.
|
||||||
|
|
||||||
<a id="in-mem-web-api"></a>
|
<a id="in-mem-web-api"></a>
|
||||||
.l-main-section
|
.l-main-section
|
||||||
|
|
Loading…
Reference in New Issue