docs(cookbook/a1-a2): new Angular-1 map to Angular-2 cookbook chapter
This commit is contained in:
committed by
Ward Bell
parent
f382b55629
commit
e78a04522b
@@ -0,0 +1,110 @@
|
||||
describe('Angular 1 to 2 Quick Reference Tests', function () {
|
||||
|
||||
beforeAll(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
it('should display no poster images after bootstrap', function () {
|
||||
testImagesAreDisplayed(false);
|
||||
});
|
||||
|
||||
it('should display proper movie data', function () {
|
||||
// We check only a few samples
|
||||
var expectedSamples = [
|
||||
{row: 0, column: 0, element: 'img', attr: 'src', value: 'images/hero.png', contains: true},
|
||||
{row: 0, column: 2, value: 'Celeritas'},
|
||||
{row: 1, column: 3, value: 'Dec 17, 2015'},
|
||||
{row: 1, column: 5, value: '$14.95'},
|
||||
{row: 2, column: 4, value: 'PG-13'},
|
||||
{row: 2, column: 7, value: '100%'},
|
||||
{row: 2, column: 0, element: 'img', attr: 'src', value: 'images/ng-logo.png', contains: true},
|
||||
];
|
||||
|
||||
// Go through the samples
|
||||
var movieRows = getMovieRows();
|
||||
for (var i = 0; i < expectedSamples.length; i++) {
|
||||
var sample = expectedSamples[i];
|
||||
var tableCell = movieRows.get(sample.row)
|
||||
.all(by.tagName('td')).get(sample.column);
|
||||
// Check the cell or its nested element
|
||||
var elementToCheck = sample.element
|
||||
? tableCell.element(by.tagName(sample.element))
|
||||
: tableCell;
|
||||
|
||||
// Check element attribute or text
|
||||
var valueToCheck = sample.attr
|
||||
? elementToCheck.getAttribute(sample.attr)
|
||||
: elementToCheck.getText();
|
||||
|
||||
// Test for equals/contains
|
||||
if (sample.contains) {
|
||||
expect(valueToCheck).toContain(sample.value);
|
||||
} else {
|
||||
expect(valueToCheck).toEqual(sample.value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('should display images after Show Poster', function () {
|
||||
testPosterButtonClick("Show Poster", true);
|
||||
});
|
||||
|
||||
it('should hide images after Hide Poster', function () {
|
||||
testPosterButtonClick("Hide Poster", false);
|
||||
});
|
||||
|
||||
it('should display no movie when no favorite hero is specified', function () {
|
||||
testFavoriteHero(null, "Please enter your favorite hero.");
|
||||
});
|
||||
|
||||
it('should display no movie for Magneta', function () {
|
||||
testFavoriteHero("Magneta", "No movie, sorry!");
|
||||
});
|
||||
|
||||
it('should display a movie for Mr. Nice', function () {
|
||||
testFavoriteHero("Mr. Nice", "Excellent choice!");
|
||||
});
|
||||
|
||||
function testImagesAreDisplayed(isDisplayed) {
|
||||
var expectedMovieCount = 3;
|
||||
|
||||
var movieRows = getMovieRows();
|
||||
expect(movieRows.count()).toBe(expectedMovieCount);
|
||||
for (var i = 0; i < expectedMovieCount; i++) {
|
||||
var movieImage = movieRows.get(i).element(by.css('td > img'));
|
||||
expect(movieImage.isDisplayed()).toBe(isDisplayed);
|
||||
}
|
||||
}
|
||||
|
||||
function testPosterButtonClick(expectedButtonText, isDisplayed) {
|
||||
var posterButton = element(by.css('movie-list tr > th > button'));
|
||||
expect(posterButton.getText()).toBe(expectedButtonText);
|
||||
|
||||
posterButton.click().then(function () {
|
||||
testImagesAreDisplayed(isDisplayed);
|
||||
})
|
||||
}
|
||||
|
||||
function getMovieRows() {
|
||||
return element.all(by.css('movie-list tbody > tr'));
|
||||
}
|
||||
|
||||
function testFavoriteHero(heroName, expectedLabel) {
|
||||
var movieListComp = element(by.tagName('movie-list'));
|
||||
var heroInput = movieListComp.element(by.tagName('input'));
|
||||
var favoriteHeroLabel = movieListComp.element(by.tagName('h3'));
|
||||
var resultLabel = movieListComp.element(by.css('span > p'));
|
||||
|
||||
heroInput.clear().then(function () {
|
||||
sendKeys(heroInput, heroName || '').then(function () {
|
||||
expect(resultLabel.getText()).toBe(expectedLabel);
|
||||
if (heroName) {
|
||||
expect(favoriteHeroLabel.isDisplayed()).toBe(true);
|
||||
expect(favoriteHeroLabel.getText()).toContain(heroName);
|
||||
} else {
|
||||
expect(favoriteHeroLabel.isDisplayed()).toBe(false);
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
**/*.js
|
||||
@@ -0,0 +1,15 @@
|
||||
/* route-link anchor tags */
|
||||
nav a {padding: 5px; text-decoration: none; font-family: Arial, Helvetica, sans-serif; }
|
||||
nav a:visited, a:link {color: #444;}
|
||||
nav a:hover {color: white; background-color: #1171a3; }
|
||||
nav a.router-link-active {color: white; background-color: #52b9e9; }
|
||||
|
||||
.active {font-style: italic;}
|
||||
.shazam {font-weight: bold;}
|
||||
|
||||
img {height: 100px;}
|
||||
|
||||
table td {
|
||||
padding: 4px;
|
||||
border: 1px solid #e0e0e0;
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<!-- #docplaster -->
|
||||
<h1>{{title}}</h1>
|
||||
|
||||
<h3>Routed Movies</h3>
|
||||
<nav>
|
||||
<!-- #docregion router-link -->
|
||||
<a [routerLink]="['Movies']">Movies</a>
|
||||
<!-- #enddocregion router-link -->
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
|
||||
<hr>
|
||||
|
||||
<h1>Example Snippets</h1>
|
||||
|
||||
<!-- #docregion ngClass -->
|
||||
<div [ngClass]="{active: isActive}">
|
||||
<!-- #enddocregion ngClass -->
|
||||
[ngClass] active
|
||||
</div>
|
||||
<!-- #docregion ngClass -->
|
||||
<div [ngClass]="{active: isActive,
|
||||
shazam: isImportant}">
|
||||
<!-- #enddocregion ngClass -->
|
||||
[ngClass] active and boldly important
|
||||
</div>
|
||||
<!-- #docregion ngClass -->
|
||||
<div [class.active]="isActive">
|
||||
<!-- #enddocregion ngClass -->
|
||||
[class.active]
|
||||
</div>
|
||||
|
||||
<p></p>
|
||||
<!-- #docregion href -->
|
||||
<a [href]="angularDocsUrl">Angular Docs</a>
|
||||
<!-- #enddocregion href -->
|
||||
|
||||
<p></p>
|
||||
<div>
|
||||
<!-- #docregion event-binding -->
|
||||
<button (click)="toggleImage()">
|
||||
<!-- #enddocregion event-binding -->
|
||||
Image Toggle #1</button>
|
||||
<!-- #docregion event-binding -->
|
||||
<button (click)="toggleImage($event)">
|
||||
<!-- #enddocregion event-binding -->
|
||||
Image Toggle #2</button>
|
||||
<p>Image toggle event type was {{eventType}}</p>
|
||||
</div>
|
||||
|
||||
<p></p>
|
||||
<div *ngIf="showImage">
|
||||
<!-- #docregion src -->
|
||||
<img [src]="movie.imageurl">
|
||||
<!-- #enddocregion src -->
|
||||
</div>
|
||||
|
||||
<p></p>
|
||||
<!-- #docregion ngStyle -->
|
||||
<div [ngStyle]="{color: colorPreference}">
|
||||
<!-- #enddocregion ngStyle -->
|
||||
color preference #1
|
||||
</div>
|
||||
<!-- #docregion ngStyle -->
|
||||
<div [style.color]="colorPreference">
|
||||
<!-- #enddocregion ngStyle -->
|
||||
color preference #2
|
||||
</div>
|
||||
|
||||
<h3>Movie as JSON</h3>
|
||||
<!-- #docregion json -->
|
||||
<pre>{{movie | json}}</pre>
|
||||
<!-- #enddocregion json -->
|
||||
|
||||
<h3>Movie Titles via local variable</h3>
|
||||
<table>
|
||||
<!-- #docregion local -->
|
||||
<tr *ngFor="#movie of movies">
|
||||
<td>{{movie.title}}</td>
|
||||
</tr>
|
||||
<!-- #enddocregion local -->
|
||||
</table>
|
||||
|
||||
<h3>Sliced Movies with pipes</h3>
|
||||
<table>
|
||||
<!-- #docregion slice -->
|
||||
<tr *ngFor="#movie of movies | slice:0:2">
|
||||
<!-- #enddocregion slice -->
|
||||
|
||||
<!-- #docregion uppercase -->
|
||||
<td>{{movie.title | uppercase}}</td>
|
||||
<!-- #enddocregion uppercase -->
|
||||
|
||||
<!-- #docregion lowercase -->
|
||||
<td>{{movie.title | lowercase}}</td>
|
||||
<!-- #enddocregion lowercase -->
|
||||
|
||||
<!-- #docregion date -->
|
||||
<td>{{movie.releaseDate | date}}</td>
|
||||
<!-- #enddocregion date -->
|
||||
|
||||
<!-- #docregion currency -->
|
||||
<td>{{movie.price | currency:'USD':true}}</td>
|
||||
<!-- #enddocregion currency -->
|
||||
|
||||
<!-- #docregion number -->
|
||||
<td>{{movie.starRating | number}}</td>
|
||||
<td>{{movie.starRating | number:'1.1-2'}}</td>
|
||||
<td>{{movie.approvalRating | percent: '1.0-2'}}</td>
|
||||
<!-- #enddocregion number -->
|
||||
|
||||
</tr></table>
|
||||
@@ -0,0 +1,40 @@
|
||||
import {Component} from 'angular2/core';
|
||||
import {RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS} from "angular2/router";
|
||||
|
||||
import {MovieListComponent} from './movie-list.component';
|
||||
import {MovieService} from './movie.service';
|
||||
import {IMovie} from './movie';
|
||||
import {StringSafeDatePipe} from './date.pipe';
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
templateUrl: 'app/app.component.html',
|
||||
styleUrls: ['app/app.component.css'],
|
||||
directives: [MovieListComponent, ROUTER_DIRECTIVES],
|
||||
pipes: [StringSafeDatePipe],
|
||||
providers: [MovieService, ROUTER_PROVIDERS]
|
||||
})
|
||||
@RouteConfig([
|
||||
{path: '/movies', name: 'Movies', component: MovieListComponent, useAsDefault: true}
|
||||
])
|
||||
export class AppComponent {
|
||||
|
||||
angularDocsUrl = "https://angular.io/";
|
||||
colorPreference = 'red';
|
||||
eventType = '<not clicked yet>';
|
||||
isActive = true;
|
||||
isImportant = true;
|
||||
movie: IMovie = null;
|
||||
movies: IMovie[] = [];
|
||||
showImage = true;
|
||||
title: string = "A1-A2 Quick Ref Cookbook";
|
||||
toggleImage(event:UIEvent) {
|
||||
this.showImage = !this.showImage;
|
||||
this.eventType = (event && event.type) || 'not provided';
|
||||
}
|
||||
|
||||
constructor(movieService: MovieService) {
|
||||
this.movies = movieService.getMovies();
|
||||
this.movie = this.movies[0];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import {Injectable, Pipe} from 'angular2/core';
|
||||
import {DatePipe} from 'angular2/common';
|
||||
|
||||
@Injectable()
|
||||
// #docregion date-pipe
|
||||
@Pipe({name: 'date', pure: true})
|
||||
export class StringSafeDatePipe extends DatePipe {
|
||||
transform(value: any, args: any[]): string {
|
||||
value = typeof value === 'string' ?
|
||||
Date.parse(value) : value
|
||||
return super.transform(value, args);
|
||||
}
|
||||
}
|
||||
// #enddocregion date-pipe
|
||||
@@ -0,0 +1,5 @@
|
||||
// #docregion
|
||||
import {bootstrap} from 'angular2/platform/browser';
|
||||
import {AppComponent} from './app.component';
|
||||
|
||||
bootstrap(AppComponent);
|
||||
@@ -0,0 +1,57 @@
|
||||
div {
|
||||
font-family:Arial, Helvetica, sans-serif;
|
||||
margin:20px;
|
||||
}
|
||||
|
||||
table {
|
||||
font-family:Arial, Helvetica, sans-serif;
|
||||
color:#666;
|
||||
font-size:14px;
|
||||
text-shadow: 1px 1px 0px #fff;
|
||||
margin:20px;
|
||||
border:#ccc 1px solid;
|
||||
|
||||
-moz-border-radius:3px;
|
||||
-webkit-border-radius:3px;
|
||||
border-radius:3px;
|
||||
}
|
||||
table th {
|
||||
padding:21px 25px 22px 25px;
|
||||
border-top:1px solid #fafafa;
|
||||
border-bottom:1px solid #e0e0e0;
|
||||
border-left: 1px solid #e0e0e0;
|
||||
font-weight: bold;
|
||||
}
|
||||
table th:first-child {
|
||||
text-align: left;
|
||||
padding-left:20px;
|
||||
border-left: 0;
|
||||
}
|
||||
table tr {
|
||||
text-align: center;
|
||||
padding-left:20px;
|
||||
}
|
||||
table td:first-child {
|
||||
text-align: left;
|
||||
padding-left:20px;
|
||||
border-left: 0;
|
||||
}
|
||||
table td {
|
||||
padding:18px;
|
||||
border-top: 1px solid #ffffff;
|
||||
border-bottom:1px solid #e0e0e0;
|
||||
border-left: 1px solid #e0e0e0;
|
||||
}
|
||||
table tr:last-child td {
|
||||
border-bottom:0;
|
||||
}
|
||||
table tr:last-child td:first-child {
|
||||
-moz-border-radius-bottomleft:3px;
|
||||
-webkit-border-bottom-left-radius:3px;
|
||||
border-bottom-left-radius:3px;
|
||||
}
|
||||
table tr:last-child td:last-child {
|
||||
-moz-border-radius-bottomright:3px;
|
||||
-webkit-border-bottom-right-radius:3px;
|
||||
border-bottom-right-radius:3px;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<!-- Filter the Movie Title -->
|
||||
<div>
|
||||
<h2>Movie List</h2>
|
||||
<div>Who is your favorite hero?</div>
|
||||
<div>
|
||||
<!-- #docregion ngModel -->
|
||||
<input [(ngModel)]="favoriteHero" />
|
||||
<!-- #enddocregion ngModel -->
|
||||
|
||||
<!-- #docregion ngSwitch-->
|
||||
<span [ngSwitch]="favoriteHero &&
|
||||
checkMovieHero(favoriteHero)">
|
||||
<p *ngSwitchWhen="true">
|
||||
Excellent choice!
|
||||
</p>
|
||||
<p *ngSwitchWhen="false">
|
||||
No movie, sorry!
|
||||
</p>
|
||||
<p *ngSwitchDefault>
|
||||
Please enter your favorite hero.
|
||||
</p>
|
||||
</span>
|
||||
<!-- #enddocregion ngSwitch-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- #docregion hidden -->
|
||||
<h3 [hidden]="!favoriteHero">
|
||||
<!-- #docregion interpolation -->
|
||||
Your favorite hero is: {{favoriteHero}}
|
||||
<!-- #enddocregion interpolation -->
|
||||
</h3>
|
||||
<!-- #enddocregion hidden -->
|
||||
|
||||
<div>
|
||||
<!-- #docregion ngIf -->
|
||||
<table *ngIf="movies.length">
|
||||
<!-- #enddocregion ngIf -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<button (click)="toggleImage()">
|
||||
{{showImage ? "Hide" : "Show"}} Poster
|
||||
</button>
|
||||
</th>
|
||||
<th>Title</th>
|
||||
<th>Hero</th>
|
||||
<th>Release Date</th>
|
||||
<th>Rating</th>
|
||||
<th>Price</th>
|
||||
<th>Star rating</th>
|
||||
<th>Approval rating</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- #docregion ngFor -->
|
||||
<tr *ngFor="#movie of movies">
|
||||
<!-- #enddocregion ngFor -->
|
||||
<td>
|
||||
<img [hidden]="!showImage || !movie.imageurl"
|
||||
[style.height.px]="50"
|
||||
[style.margin.px]="2"
|
||||
[src]="movie.imageurl"
|
||||
[title]="movie.title">
|
||||
</td>
|
||||
<td>{{movie.title}}</td>
|
||||
<td>{{movie.hero}}</td>
|
||||
<td>{{movie.releaseDate | date}}</td>
|
||||
<td>{{movie.mpaa | uppercase}}</td>
|
||||
<!-- #docregion currency -->
|
||||
<td>{{movie.price | currency:'USD':true}}</td>
|
||||
<!-- #enddocregion currency -->
|
||||
<td>{{movie.starRating | number:'1.1-2'}}</td>
|
||||
<td>{{movie.approvalRating | percent: '1.0-0'}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -0,0 +1,48 @@
|
||||
// #docplaster
|
||||
// #docregion import
|
||||
import {Component} from 'angular2/core';
|
||||
import {ROUTER_DIRECTIVES} from "angular2/router";
|
||||
// #enddocregion import
|
||||
import {MovieService} from './movie.service';
|
||||
import {IMovie} from './movie';
|
||||
import {StringSafeDatePipe} from './date.pipe';
|
||||
|
||||
|
||||
// #docregion component
|
||||
@Component({
|
||||
selector: 'movie-list',
|
||||
templateUrl:'app/movie-list.component.html',
|
||||
// #enddocregion component
|
||||
// #docregion style-url
|
||||
styleUrls: ['app/movie-list.component.css'],
|
||||
// #enddocregion style-url
|
||||
// #docregion date-pipe
|
||||
pipes: [StringSafeDatePipe]
|
||||
// #enddocregion date-pipe
|
||||
})
|
||||
// #enddocregion component
|
||||
// #docregion class
|
||||
export class MovieListComponent {
|
||||
// #enddocregion class
|
||||
favoriteHero: string;
|
||||
showImage: boolean = false;
|
||||
movies: IMovie[];
|
||||
|
||||
// #docregion di
|
||||
constructor(movieService: MovieService) {
|
||||
// #enddocregion di
|
||||
this.movies = movieService.getMovies();
|
||||
// #docregion di
|
||||
}
|
||||
// #enddocregion di
|
||||
|
||||
toggleImage(): void {
|
||||
this.showImage = !this.showImage;
|
||||
}
|
||||
|
||||
checkMovieHero(value: string): boolean {
|
||||
return this.movies.filter(movie => movie.hero === value).length > 0 ;
|
||||
}
|
||||
// #docregion class
|
||||
}
|
||||
// #enddocregion class
|
||||
@@ -0,0 +1,43 @@
|
||||
import {Injectable} from 'angular2/core';
|
||||
import {IMovie} from './movie';
|
||||
|
||||
@Injectable()
|
||||
export class MovieService {
|
||||
getMovies() : IMovie[] {
|
||||
return [
|
||||
{
|
||||
hero: "Celeritas",
|
||||
imageurl: "images/hero.png",
|
||||
movieId: 1,
|
||||
mpaa: "pg-13",
|
||||
releaseDate: "2015-12-19T00:00:00",
|
||||
title: "Celeritas Reigns",
|
||||
price: 12.95,
|
||||
starRating: 4.925,
|
||||
approvalRating: .97
|
||||
},
|
||||
{
|
||||
hero: "Mr. Nice",
|
||||
imageurl: "images/villain.png",
|
||||
movieId: 2,
|
||||
mpaa: "pg-13",
|
||||
releaseDate: "2015-12-18T00:00:00",
|
||||
title: "No More Mr. Nice Guy",
|
||||
price: 14.95,
|
||||
starRating: 4.6,
|
||||
approvalRating: .94
|
||||
},
|
||||
{
|
||||
hero: "Angular",
|
||||
imageurl: "images/ng-logo.png",
|
||||
movieId: 3,
|
||||
mpaa: "pg-13",
|
||||
releaseDate: "2015-12-17T00:00:00",
|
||||
title: "Angular to the Rescue",
|
||||
price: 15.95,
|
||||
starRating: 4.98,
|
||||
approvalRating: .9995
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/* Defines the movie entity */
|
||||
export interface IMovie {
|
||||
approvalRating: number;
|
||||
hero: string;
|
||||
imageurl: string;
|
||||
movieId: number;
|
||||
mpaa: string;
|
||||
price: number;
|
||||
releaseDate: string;
|
||||
starRating: number;
|
||||
title: string;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 8.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
@@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<base href="/">
|
||||
<title>Angular 1 to Angular 2 Quick Reference</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- IE required polyfills, in this exact order -->
|
||||
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
|
||||
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>
|
||||
|
||||
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
|
||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||
<script src="node_modules/rxjs/bundles/Rx.js"></script>
|
||||
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
|
||||
<script src="node_modules/angular2/bundles/router.dev.js"></script>
|
||||
<script>
|
||||
System.config({
|
||||
packages: {
|
||||
app: {
|
||||
format: 'register',
|
||||
defaultExtension: 'js'
|
||||
}
|
||||
}
|
||||
});
|
||||
System.import('app/main')
|
||||
.then(null, console.error.bind(console));
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<my-app>Loading app...</my-app>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"description": "Angular 1 to Angular 2 Quick Reference",
|
||||
"files":[
|
||||
"!**/*.d.ts",
|
||||
"!**/*.js",
|
||||
"!**/*.[1].*"
|
||||
],
|
||||
"tags":["cookbook"]
|
||||
}
|
||||
@@ -5,7 +5,11 @@
|
||||
"title": "Cookbook"
|
||||
},
|
||||
|
||||
"a1-a2-quick-reference": {
|
||||
"title": "Angular 1 to 2 Quick Ref"
|
||||
},
|
||||
|
||||
"component-communication": {
|
||||
"title": "Component Communication"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@
|
||||
"cheatsheet": {
|
||||
"title": "Angular Cheat Sheet"
|
||||
},
|
||||
|
||||
|
||||
"architecture": {
|
||||
"title": "Architecture Overview"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user