docs(pipes): improve FetchJsonPipe discussion (#2923)
This commit is contained in:
parent
977492a290
commit
93c78dae10
|
@ -1,6 +1,7 @@
|
|||
// #docregion
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { Http } from '@angular/http';
|
||||
import './rxjs-extensions';
|
||||
|
||||
// #docregion pipe-metadata
|
||||
@Pipe({
|
||||
|
@ -9,20 +10,20 @@ import { Http } from '@angular/http';
|
|||
})
|
||||
// #enddocregion pipe-metadata
|
||||
export class FetchJsonPipe implements PipeTransform {
|
||||
private fetchedJson: any = null;
|
||||
private prevUrl = '';
|
||||
private cachedData: any = null;
|
||||
private cachedUrl = '';
|
||||
|
||||
constructor(private _http: Http) { }
|
||||
constructor(private http: Http) { }
|
||||
|
||||
transform(url: string): any {
|
||||
if (url !== this.prevUrl) {
|
||||
this.prevUrl = url;
|
||||
this.fetchedJson = null;
|
||||
this._http.get(url)
|
||||
if (url !== this.cachedUrl) {
|
||||
this.cachedData = null;
|
||||
this.cachedUrl = url;
|
||||
this.http.get(url)
|
||||
.map( result => result.json() )
|
||||
.subscribe( result => this.fetchedJson = result );
|
||||
.subscribe( result => this.cachedData = result );
|
||||
}
|
||||
|
||||
return this.fetchedJson;
|
||||
return this.cachedData;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import './rxjs-extensions';
|
||||
|
||||
@Component({
|
||||
selector: 'hero-message',
|
||||
|
|
|
@ -3,7 +3,6 @@ import { Component } from '@angular/core';
|
|||
|
||||
@Component({
|
||||
selector: 'hero-list',
|
||||
// #docregion template
|
||||
template: `
|
||||
<h2>Heroes from JSON File</h2>
|
||||
|
||||
|
@ -12,9 +11,7 @@ import { Component } from '@angular/core';
|
|||
</div>
|
||||
|
||||
<p>Heroes as JSON:
|
||||
{{'heroes.json' | fetch | json}}
|
||||
</p>
|
||||
`
|
||||
// #enddocregion template
|
||||
{{'heroes.json' | fetch | json}}
|
||||
</p>`
|
||||
})
|
||||
export class HeroListComponent { }
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// #docregion
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import 'rxjs/Rx';
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
// Extensions to RxJS used in this app.
|
||||
import 'rxjs/add/observable/interval';
|
||||
|
||||
import 'rxjs/add/operator/map';
|
||||
import 'rxjs/add/operator/take';
|
|
@ -361,44 +361,42 @@ h3#async-pipe The impure #[i AsyncPipe]
|
|||
The component doesn't have to subscribe to the async data source,
|
||||
it doesn't extract the resolved values and expose them for binding,
|
||||
and the component doesn't have to unsubscribe when it is destroyed
|
||||
(a potent source of memory leaks).
|
||||
(a potential source of memory leaks).
|
||||
|
||||
### An impure caching pipe
|
||||
|
||||
Let's write one more impure pipe, a pipe that makes an HTTP request to the server.
|
||||
Normally, that's a horrible idea.
|
||||
It's probably a horrible idea no matter what we do.
|
||||
We're forging ahead anyway to make a point.
|
||||
Remember that impure pipes are called every few microseconds.
|
||||
Let's write one more impure pipe, a pipe that makes an HTTP request.
|
||||
|
||||
Remember that impure pipes are called every few milliseconds.
|
||||
If we're not careful, this pipe will punish the server with requests.
|
||||
|
||||
We are careful. Our pipe only makes a server call if the request URL has changed.
|
||||
It caches the request URL and waits for a result which it also caches when it arrives.
|
||||
The pipe returns the cached result (which is null while a request is in flight)
|
||||
after every Angular call and only contacts the server as necessary.
|
||||
|
||||
Here's the code, which uses the [Angular http](server-communication.html) facility
|
||||
to retrieve a `heroes.json` file:
|
||||
We are careful.
|
||||
The pipe only calls the server when the request URL changes and it caches the server response.
|
||||
Here's the code, which uses the [Angular http](server-communication.html) client to retrieve data:
|
||||
|
||||
+makeExample('pipes/ts/app/fetch-json.pipe.ts', null, 'app/fetch-json.pipe.ts')
|
||||
:marked
|
||||
Then we demonstrate it in a harness component whose template defines two bindings to this pipe.
|
||||
+makeExample('pipes/ts/app/hero-list.component.ts', 'template', 'app/hero-list.component.ts (template)')
|
||||
:marked
|
||||
Despite the two bindings and what we know to be frequent pipe calls,
|
||||
the nework tab in the browser developer tools confirms that there is only one request for the file.
|
||||
Then we demonstrate it in a harness component whose template defines two bindings to this pipe,
|
||||
both requesting the heroes from the `heroes.json` file.
|
||||
|
||||
+makeExample('pipes/ts/app/hero-list.component.ts', null, 'app/hero-list.component.ts')
|
||||
:marked
|
||||
The component renders like this:
|
||||
|
||||
figure.image-display
|
||||
img(src='/resources/images/devguide/pipes/hero-list.png' alt="Hero List")
|
||||
|
||||
:marked
|
||||
A breakpoint on the pipe's request for data shows that
|
||||
* each binding gets its own pipe instance
|
||||
* each pipe instance caches its own url and data
|
||||
* each pipe instance only calls the server once
|
||||
|
||||
:marked
|
||||
### *JsonPipe*
|
||||
|
||||
The second binding involving the `FetchPipe` uses more pipe chaining.
|
||||
We take the same fetched results displayed in the first binding
|
||||
and display them again, this time in JSON format by chaining through to the built-in `JsonPipe`.
|
||||
The second `fetch` pipe binding above demonstrates more pipe chaining.
|
||||
It displays the same hero data in JSON format by chaining through to the built-in `JsonPipe`.
|
||||
|
||||
.callout.is-helpful
|
||||
header Debugging with the json pipe
|
||||
|
@ -406,12 +404,7 @@ figure.image-display
|
|||
The [JsonPipe](../api/common/index/JsonPipe-pipe.html)
|
||||
provides an easy way to diagnosis a mysteriously failing data binding or
|
||||
inspect an object for future binding.
|
||||
|
||||
:marked
|
||||
Here's the complete component implementation:
|
||||
|
||||
+makeExample('pipes/ts/app/hero-list.component.ts', null, 'app/hero-list.component.ts')
|
||||
|
||||
|
||||
a(id="pure-pipe-pure-fn")
|
||||
:marked
|
||||
### Pure pipes and pure functions
|
||||
|
|
|
@ -365,40 +365,38 @@ h3#async-pipe The impure #[i AsyncPipe]
|
|||
|
||||
### An impure caching pipe
|
||||
|
||||
Let's write one more impure pipe, a pipe that makes an HTTP request to the server.
|
||||
Normally, that's a horrible idea.
|
||||
It's probably a horrible idea no matter what we do.
|
||||
We're forging ahead anyway to make a point.
|
||||
Remember that impure pipes are called every few microseconds.
|
||||
Let's write one more impure pipe, a pipe that makes an HTTP request.
|
||||
|
||||
Remember that impure pipes are called every few milliseconds.
|
||||
If we're not careful, this pipe will punish the server with requests.
|
||||
|
||||
We are careful. Our pipe only makes a server call if the request URL has changed.
|
||||
It caches the request URL and waits for a result which it also caches when it arrives.
|
||||
The pipe returns the cached result (which is null while a request is in flight)
|
||||
after every Angular call and only contacts the server as necessary.
|
||||
|
||||
Here's the code, which uses the [Angular http](server-communication.html) facility
|
||||
to retrieve a `heroes.json` file:
|
||||
We are careful.
|
||||
The pipe only calls the server when the request URL changes and it caches the server response.
|
||||
Here's the code, which uses the [Angular http](server-communication.html) client to retrieve data:
|
||||
|
||||
+makeExample('pipes/ts/app/fetch-json.pipe.ts', null, 'app/fetch-json.pipe.ts')
|
||||
:marked
|
||||
Then we demonstrate it in a harness component whose template defines two bindings to this pipe.
|
||||
+makeExample('pipes/ts/app/hero-list.component.ts', 'template', 'app/hero-list.component.ts (template)')
|
||||
:marked
|
||||
Despite the two bindings and what we know to be frequent pipe calls,
|
||||
the nework tab in the browser developer tools confirms that there is only one request for the file.
|
||||
Then we demonstrate it in a harness component whose template defines two bindings to this pipe,
|
||||
both requesting the heroes from the `heroes.json` file.
|
||||
|
||||
+makeExample('pipes/ts/app/hero-list.component.ts', null, 'app/hero-list.component.ts')
|
||||
:marked
|
||||
The component renders like this:
|
||||
|
||||
figure.image-display
|
||||
img(src='/resources/images/devguide/pipes/hero-list.png' alt="Hero List")
|
||||
|
||||
:marked
|
||||
A breakpoint on the pipe's request for data shows that
|
||||
* each binding gets its own pipe instance
|
||||
* each pipe instance caches its own url and data
|
||||
* each pipe instance only calls the server once
|
||||
|
||||
:marked
|
||||
### *JsonPipe*
|
||||
|
||||
The second binding involving the `FetchPipe` uses more pipe chaining.
|
||||
We take the same fetched results displayed in the first binding
|
||||
and display them again, this time in JSON format by chaining through to the built-in `JsonPipe`.
|
||||
The second `fetch` pipe binding above demonstrates more pipe chaining.
|
||||
It displays the same hero data in JSON format by chaining through to the built-in `JsonPipe`.
|
||||
|
||||
.callout.is-helpful
|
||||
header Debugging with the json pipe
|
||||
|
@ -407,11 +405,6 @@ figure.image-display
|
|||
provides an easy way to diagnosis a mysteriously failing data binding or
|
||||
inspect an object for future binding.
|
||||
|
||||
:marked
|
||||
Here's the complete component implementation:
|
||||
|
||||
+makeExample('pipes/ts/app/hero-list.component.ts', null, 'app/hero-list.component.ts')
|
||||
|
||||
a(id="pure-pipe-pure-fn")
|
||||
:marked
|
||||
### Pure pipes and pure functions
|
||||
|
|
Loading…
Reference in New Issue