parent
8fe40026c1
commit
4ff636d24d
|
@ -102,7 +102,7 @@ describe('Pipes', () => {
|
|||
});
|
||||
|
||||
it('should show an async hero message', async () => {
|
||||
expect(await element.all(by.tagName('app-hero-message')).get(0).getText()).toContain('hero');
|
||||
expect(await element.all(by.tagName('app-hero-async-message')).get(0).getText()).toContain('hero');
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
<a id="toc"></a>
|
||||
<h1>Pipes</h1>
|
||||
<a href="#happy-birthday1">Happy Birthday v1</a><br>
|
||||
<a href="#birthday-date-pipe">Birthday DatePipe</a><br>
|
||||
<a href="#happy-birthday2">Happy Birthday v2</a><br>
|
||||
<a href="#birthday-pipe-chaining">Birthday Pipe Chaining</a><br>
|
||||
<a href="#power-booster">Power Booster custom pipe</a><br>
|
||||
<a href="#power-boost-calc">Power Boost Calculator custom pipe with params</a><br>
|
||||
<a href="#flying-heroes">Flying Heroes filter pipe (pure)</a><br>
|
||||
<a href="#flying-heroes-impure">Flying Heroes filter pipe (impure)</a><br>
|
||||
<a href="#hero-message">Async Hero Message and AsyncPipe</a><br>
|
||||
<a href="#hero-list">Hero List with caching FetchJsonPipe</a><br>
|
||||
<a href="#pipe-precedence">Pipes and Precedence</a><br>
|
||||
<a href="#happy-birthday1">Happy Birthday v1</a>
|
||||
<a href="#birthday-date-pipe">Birthday DatePipe</a>
|
||||
<a href="#happy-birthday2">Happy Birthday v2</a>
|
||||
<a href="#birthday-pipe-chaining">Birthday Pipe Chaining</a>
|
||||
<a href="#power-booster">Power Booster custom pipe</a>
|
||||
<a href="#power-boost-calc">Power Boost Calculator custom pipe with params</a>
|
||||
<a href="#flying-heroes">Flying Heroes filter pipe (pure)</a>
|
||||
<a href="#flying-heroes-impure">Flying Heroes filter pipe (impure)</a>
|
||||
<a href="#hero-message">Async Hero Message and AsyncPipe</a>
|
||||
<a href="#hero-list">Hero List with caching FetchJsonPipe</a>
|
||||
<a href="#pipe-precedence">Pipes and Precedence</a>
|
||||
|
||||
|
||||
<hr>
|
||||
|
@ -73,7 +73,7 @@
|
|||
<hr>
|
||||
<a id="hero-message"></a>
|
||||
<!-- async examples at the top so can see them in action -->
|
||||
<app-hero-message></app-hero-message>
|
||||
<app-hero-async-message></app-hero-async-message>
|
||||
|
||||
<hr>
|
||||
<a id="hero-list"></a>
|
||||
|
|
|
@ -3,7 +3,8 @@ import { Component } from '@angular/core';
|
|||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html'
|
||||
templateUrl: './app.component.html',
|
||||
styles: ['a[href] {display: block; padding: 10px 0;}', 'a:hover {text-decoration: none;}', 'h2 {margin: 0;}']
|
||||
})
|
||||
export class AppComponent {
|
||||
birthday = new Date(1988, 3, 15); // April 15, 1988 -- since month parameter is zero-based
|
||||
|
|
|
@ -1,19 +1,24 @@
|
|||
<!-- #docplaster-->
|
||||
<!-- #docregion -->
|
||||
<h2>{{title}}</h2>
|
||||
<p>
|
||||
New hero:
|
||||
<input type="text" #box
|
||||
(keyup.enter)="addHero(box.value); box.value=''"
|
||||
placeholder="hero name">
|
||||
<input id="can-fly" type="checkbox" [(ngModel)]="canFly"> can fly
|
||||
</p>
|
||||
<p>
|
||||
|
||||
<label for="hero-name">New hero: </label>
|
||||
<input type="text"
|
||||
id="hero-name"
|
||||
#box
|
||||
(keyup.enter)="addHero(box.value); box.value=''"
|
||||
placeholder="hero name">
|
||||
<div>
|
||||
<input id="can-fly" type="checkbox" [(ngModel)]="canFly">
|
||||
<label for="can-fly">can fly</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input id="mutate" type="checkbox" [(ngModel)]="mutate">Mutate array
|
||||
<button (click)="reset()">Reset</button>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h4>Heroes who fly (piped)</h4>
|
||||
<h3>Heroes who fly (piped)</h3>
|
||||
<div id="flyers">
|
||||
<!-- #docregion template-flying-heroes -->
|
||||
<div *ngFor="let hero of (heroes | flyingHeroesImpure)">
|
||||
|
@ -22,7 +27,7 @@ New hero:
|
|||
<!-- #enddocregion template-flying-heroes -->
|
||||
</div>
|
||||
|
||||
<h4>All Heroes (no pipe)</h4>
|
||||
<h3>All Heroes (no pipe)</h3>
|
||||
<div id="all">
|
||||
<div *ngFor="let hero of heroes">
|
||||
{{hero.name}}
|
||||
|
|
|
@ -1,23 +1,27 @@
|
|||
<!-- #docplaster-->
|
||||
<!-- #docregion -->
|
||||
<h2>{{title}}</h2>
|
||||
<p>
|
||||
<p>Create a new hero and press enter to add it to the list. </p>
|
||||
<!-- #docregion template-1 -->
|
||||
New hero:
|
||||
<input type="text" #box
|
||||
(keyup.enter)="addHero(box.value); box.value=''"
|
||||
placeholder="hero name">
|
||||
<label for="hero-name">New hero name: </label>
|
||||
<input type="text" #box
|
||||
id="hero-name"
|
||||
(keyup.enter)="addHero(box.value); box.value=''"
|
||||
placeholder="hero name">
|
||||
<!-- #enddocregion template-1 -->
|
||||
<input id="can-fly" type="checkbox" [(ngModel)]="canFly"> can fly
|
||||
</p>
|
||||
<p>
|
||||
<input id="mutate" type="checkbox" [(ngModel)]="mutate">Mutate array
|
||||
<div>
|
||||
<input id="can-fly" type="checkbox" [(ngModel)]="canFly">
|
||||
<label for="can-fly">Hero can fly</label>
|
||||
</div>
|
||||
<div>
|
||||
<input id="mutate" type="checkbox" [(ngModel)]="mutate">
|
||||
<label for="mutate">Mutate array</label>
|
||||
<!-- #docregion template-1 -->
|
||||
<button (click)="reset()">Reset</button>
|
||||
<button (click)="reset()">Reset list of heroes</button>
|
||||
<!-- #enddocregion template-1 -->
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h4>Heroes who fly (piped)</h4>
|
||||
<h3>Heroes who fly (piped)</h3>
|
||||
<div id="flyers">
|
||||
<!-- #docregion template-flying-heroes -->
|
||||
<div *ngFor="let hero of (heroes | flyingHeroes)">
|
||||
|
@ -26,7 +30,7 @@ New hero:
|
|||
<!-- #enddocregion template-flying-heroes -->
|
||||
</div>
|
||||
|
||||
<h4>All Heroes (no pipe)</h4>
|
||||
<h3>All Heroes (no pipe)</h3>
|
||||
<div id="all">
|
||||
<!-- #docregion template-1 -->
|
||||
<div *ngFor="let hero of heroes">
|
||||
|
|
|
@ -7,7 +7,7 @@ import { HEROES } from './heroes';
|
|||
@Component({
|
||||
selector: 'app-flying-heroes',
|
||||
templateUrl: './flying-heroes.component.html',
|
||||
styles: ['#flyers, #all {font-style: italic}']
|
||||
styles: ['#flyers, #all {font-style: italic}', 'button {display: block}', 'input {margin: .25rem .25rem .5rem 0;}']
|
||||
})
|
||||
// #docregion v1
|
||||
export class FlyingHeroesComponent {
|
||||
|
@ -48,7 +48,7 @@ export class FlyingHeroesComponent {
|
|||
@Component({
|
||||
selector: 'app-flying-heroes-impure',
|
||||
templateUrl: './flying-heroes-impure.component.html',
|
||||
styles: ['.flyers, .all {font-style: italic}'],
|
||||
styles: ['#flyers, #all {font-style: italic}', 'button {display: block}', 'input {margin: .25rem .25rem .5rem 0;}'],
|
||||
})
|
||||
export class FlyingHeroesImpureComponent extends FlyingHeroesComponent {
|
||||
title = 'Flying Heroes (impure pipe)';
|
||||
|
|
|
@ -5,7 +5,7 @@ import { Observable, interval } from 'rxjs';
|
|||
import { map, take } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'app-hero-message',
|
||||
selector: 'app-hero-async-message',
|
||||
template: `
|
||||
<h2>Async Hero Message and AsyncPipe</h2>
|
||||
<p>Message: {{ message$ | async }}</p>
|
||||
|
|
|
@ -5,12 +5,15 @@ import { Component } from '@angular/core';
|
|||
selector: 'app-power-boost-calculator',
|
||||
template: `
|
||||
<h2>Power Boost Calculator</h2>
|
||||
<div>Normal power: <input [(ngModel)]="power"></div>
|
||||
<div>Boost factor: <input [(ngModel)]="factor"></div>
|
||||
<label for="power-input">Normal power: </label>
|
||||
<input id="power-input" type="text" [(ngModel)]="power">
|
||||
<label for="boost-input">Boost factor: </label>
|
||||
<input id="boost-input" type="text" [(ngModel)]="factor">
|
||||
<p>
|
||||
Super Hero Power: {{power | exponentialStrength: factor}}
|
||||
</p>
|
||||
`
|
||||
`,
|
||||
styles: ['input {margin: .5rem 0;}']
|
||||
})
|
||||
export class PowerBoostCalculatorComponent {
|
||||
power = 5;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<h2>{{title}}</h2>
|
||||
|
||||
<p>Basic uppercase pipe (no precedence considerations necessary): {{ 'text' | uppercase }}</p>
|
||||
<p>The following shows that a pipe has higher precedence than a ternary operator. If the pipe precedence were lower than the ternary operator precedence, the output would be 'TRUE'. Instead it is: {{ true ? 'true' : 'false' | uppercase }}</p>
|
||||
<p>The following shows that a pipe has higher precedence than a ternary operator. If the pipe precedence were lower than the ternary operator precedence, the output would be in uppercase as in 'TRUE'. Instead "true" is lowercase: {{ true ? 'true' : 'false' | uppercase }}</p>
|
||||
<p>The following shows how parentheses help Angular evaluate the whole statement:
|
||||
<!-- #docregion precedence -->
|
||||
<!-- use parentheses in the third operand so the pipe applies to the whole expression -->
|
||||
|
|
|
@ -2,8 +2,7 @@ import { Component } from '@angular/core';
|
|||
|
||||
@Component({
|
||||
selector: 'app-precedence',
|
||||
templateUrl: './precedence.component.html',
|
||||
styles: []
|
||||
templateUrl: './precedence.component.html'
|
||||
})
|
||||
|
||||
export class PrecedenceComponent {
|
||||
|
|
|
@ -100,13 +100,7 @@ The tabs in the following example demonstrates toggling between two different fo
|
|||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
Clicking the **Toggle Format** button alternates the date format between **04/15/1988** and **Friday, April 15, 1988** as shown in Figure 1.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/pipes/date-format-toggle-anim.gif' alt="Date Format Toggle">
|
||||
</div>
|
||||
|
||||
**Figure 1.** Clicking the button toggles the date format
|
||||
Clicking the **Toggle Format** button alternates the date format between **04/15/1988** and **Friday, April 15, 1988**.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
|
@ -176,7 +170,6 @@ The following code example shows two component definitions:
|
|||
It defines an argument to the `transform` method (`exponent`) for a parameter passed to the pipe.
|
||||
|
||||
* The `power-booster.component.ts` component demonstrates how to use the pipe, specifying a value (`2`) and the exponent parameter (`10`).
|
||||
Figure 2 shows the output.
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
|
@ -189,11 +182,15 @@ Figure 2 shows the output.
|
|||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/pipes/power-booster.png' alt="Power Booster">
|
||||
</div>
|
||||
The browser displays the following:
|
||||
|
||||
**Figure 2.** Output from the `exponentialStrength` pipe
|
||||
<code-example language="none">
|
||||
|
||||
Power Booster
|
||||
|
||||
Superpower boost: 1024
|
||||
|
||||
</code-example>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
|
@ -214,13 +211,7 @@ For example, you could change the previous custom pipe example to use two-way da
|
|||
|
||||
</code-example>
|
||||
|
||||
The `exponentialStrength` pipe executes every time the user changes the "normal power" value or the "boost factor", as shown in Figure 3.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/pipes/power-boost-calculator-anim.gif' alt="Power Boost Calculator">
|
||||
</div>
|
||||
|
||||
**Figure 3.** Changing the amount and boost factor for the `exponentialStrength` pipe
|
||||
The `exponentialStrength` pipe executes every time the user changes the "normal power" value or the "boost factor".
|
||||
|
||||
Angular detects each change and immediately runs the pipe.
|
||||
This is fine for primitive input values.
|
||||
|
@ -306,17 +297,11 @@ You can replace the array with a new array containing the newly changed elements
|
|||
In the above example, you can create an array with the new hero appended, and assign that to `heroes`. Angular detects the change in the array reference and executes the pipe.
|
||||
|
||||
To summarize, if you mutate the input array, the pure pipe doesn't execute.
|
||||
If you *replace* the input array, the pipe executes and the display is updated, as shown in Figure 4.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/pipes/flying-heroes-anim.gif' alt="Flying Heroes">
|
||||
</div>
|
||||
|
||||
**Figure 4.** The `flyingHeroes` pipe filtering the display to flying heroes
|
||||
If you *replace* the input array, the pipe executes and the display is updated.
|
||||
|
||||
The above example demonstrates changing a component's code to accommodate a pipe.
|
||||
|
||||
To keep your component simpler and independent of HTML templates that use pipes, you can, as an alternative, use an *impure* pipe to detect changes within composite objects such as arrays, as described in the next section.
|
||||
To keep your component independent of HTML templates that use pipes, you can, as an alternative, use an *impure* pipe to detect changes within composite objects such as arrays, as described in the next section.
|
||||
|
||||
{@a impure-flying-heroes}
|
||||
|
||||
|
@ -423,13 +408,20 @@ In the above example, a breakpoint on the pipe's request for data shows the foll
|
|||
* Each binding gets its own pipe instance.
|
||||
* Each pipe instance caches its own URL and data and calls the server only once.
|
||||
|
||||
The `fetch` and `fetch-json` pipes display the heroes as shown in Figure 5.
|
||||
The `fetch` and `fetch-json` pipes display the heroes in the browser as follows:
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/pipes/hero-list.png' alt="Hero List">
|
||||
</div>
|
||||
<code-example language="none">
|
||||
|
||||
**Figure 5.** The `fetch` and `fetch-json` pipes displaying the heroes
|
||||
Heroes from JSON File
|
||||
|
||||
Windstorm
|
||||
Bombasto
|
||||
Magneto
|
||||
Tornado
|
||||
|
||||
Heroes as JSON: [ { "name": "Windstorm", "canFly": true }, { "name": "Bombasto", "canFly": false }, { "name": "Magneto", "canFly": false }, { "name": "Tornado", "canFly": true } ]
|
||||
|
||||
</code-example>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 12 KiB |
Binary file not shown.
Before Width: | Height: | Size: 53 KiB |
Binary file not shown.
Before Width: | Height: | Size: 7.1 KiB |
Loading…
Reference in New Issue