docs(cookbook/a1-a2): new Angular-1 map to Angular-2 cookbook chapter
This commit is contained in:
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,6 +5,10 @@
|
|||
"title": "Cookbook"
|
||||
},
|
||||
|
||||
"a1-a2-quick-reference": {
|
||||
"title": "Angular 1 to 2 Quick Ref"
|
||||
},
|
||||
|
||||
"component-communication": {
|
||||
"title": "Component Communication"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,795 @@
|
|||
include ../../../../_includes/_util-fns
|
||||
a(id="top")
|
||||
:marked
|
||||
There are many conceptual and syntactical differences between Angular 1 and Angular 2.
|
||||
This chapter provides a quick reference guide to some of the common Angular 1
|
||||
syntax and its equivalent in Angular 2.
|
||||
|
||||
:marked
|
||||
**See the Angular 2 syntax in this [live example](/resources/live-examples/cb-a1-a2-quick-reference/ts/plnkr.html)**.
|
||||
|
||||
## Contents
|
||||
This chapter covers
|
||||
* [Template Basics](#template-basics) - binding and local variables
|
||||
|
||||
* [Template Directives](#template-directives) - built-in directives `ngIf` and ` `ngClass`
|
||||
|
||||
* [Filters/Pipes](#filters-pipes) - built-in *filters*, known as *pipes* in Angular 2
|
||||
|
||||
* [Controllers/Components](#controllers-components) - *controllers* are *components* in Angular 2.
|
||||
Also covers modules.
|
||||
|
||||
* [Style Sheets](#style-sheets) - more options for CSS in Angular 2.
|
||||
|
||||
* [String date pipe](#string-dates) - a tip for displaying string date values.
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
## Template Basics
|
||||
Templates are the user-facing part of an Angular application and are written in HTML.
|
||||
The following are some of the key Angular 1 template features with the equivalent
|
||||
template syntax in Angular 2.
|
||||
|
||||
- var top="vertical-align:top"
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th Angular 1
|
||||
th Angular 2
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Bindings/Interpolation
|
||||
code-example.
|
||||
Your favorite hero is: {{vm.favoriteHero}}
|
||||
:marked
|
||||
In Angular 1, an expression in curly braces denotes one-way binding.
|
||||
This binds the value of the element to a property in the controller
|
||||
associated with this template.
|
||||
|
||||
When using the `controller as` syntax,
|
||||
the binding is prefixed with the controller alias (`vm`) because we
|
||||
have to be specific about the source of the binding.
|
||||
td
|
||||
:marked
|
||||
### Bindings/Interpolation
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.html', 'interpolation')(format="." )
|
||||
:marked
|
||||
In Angular 2, a template expression in curly braces still denotes one-way binding.
|
||||
This binds the value of the element to a property of the component.
|
||||
The context of the binding is implied and is always the
|
||||
associated component, so it needs no reference variable.
|
||||
|
||||
For more information see [Template Syntax](../guide/template-syntax.html#interpolation).
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Filters
|
||||
code-example.
|
||||
<td>{{movie.title | uppercase}}</td>
|
||||
:marked
|
||||
To filter output in our templates in Angular 1, we use the pipe character (|) and one or more filters.
|
||||
|
||||
In this example, we filter the `mpaa` property to uppercase.
|
||||
td
|
||||
:marked
|
||||
### Pipes
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'uppercase')(format="." )
|
||||
:marked
|
||||
In Angular 2, we use similar syntax with the pipe (|) character to filter output, but now we call them **pipes**.
|
||||
Many (but not all) of the built-in filters from Angular 1 are
|
||||
built-in pipes in Angular 2.
|
||||
|
||||
See the heading [Filters / Pipes](#Pipes) below for more information.
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Local variables
|
||||
code-example(format="").
|
||||
<tr ng-repeat="movie in vm.movies">
|
||||
<td>{{movie.title}}</td>
|
||||
</tr>
|
||||
:marked
|
||||
Here, `movie` is a user-defined local variable.
|
||||
td
|
||||
:marked
|
||||
### Local variables
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'local')(format="." )
|
||||
:marked
|
||||
In Angular 2, we have true local template variables that are explicitly defined using the hash (#) symbol.
|
||||
|
||||
Using a local template variable, we can move data between elements in the template. We can use the local template
|
||||
variable on the same element, on sibling elements, or on any child elements.
|
||||
|
||||
For more information see [Template Syntax](../guide/template-syntax.html#local-vars).
|
||||
:marked
|
||||
[Back to top](#top)
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
## Template Directives
|
||||
Angular 1 provides over seventy built-in directives for use in our templates.
|
||||
Many of them are no longer needed in Angular 2 because of its more capable and expressive binding system.
|
||||
The following are some of the key Angular 1 built-in directives and the equivalent feature in Angular 2.
|
||||
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th Angular 1
|
||||
th Angular 2
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### ng-app
|
||||
code-example.
|
||||
<body ng-app="movieHunter">
|
||||
:marked
|
||||
The application startup process is called **bootstrapping**.
|
||||
|
||||
Although we can bootstrap an Angular 1 app in code,
|
||||
many applications bootstrap declaratively with the `ng-app` directive,
|
||||
giving it the name of the application's module (`movieHunter`).
|
||||
td
|
||||
:marked
|
||||
### Bootstrapping
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/main.ts')(format="." )
|
||||
:marked
|
||||
Angular 2 does not have a bootstrap directive.
|
||||
We always launch the app in code by explicitly calling a bootstrap function
|
||||
and passing it the name of the application's module (`AppComponent`).
|
||||
|
||||
For more information see [Quick Start](../quickstart.html).
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### ng-class
|
||||
code-example(format="").
|
||||
<div ng-class="{active: isActive}">
|
||||
<div ng-class="{active: isActive,
|
||||
shazam: isImportant}">
|
||||
:marked
|
||||
In Angular 1, the `ng-class` directive includes/excludes CSS classes
|
||||
based on an expression. That expression is often a key-value control object with each
|
||||
key of the object defined as a CSS class name, and each value defined as a template expression
|
||||
that evaluates to a Boolean value.
|
||||
|
||||
In the first example, the `active` class is applied to the element if `isActive` is true.
|
||||
|
||||
We can specify multiple classes as shown in the second example.
|
||||
td
|
||||
:marked
|
||||
### ngClass
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'ngClass')(format="." )
|
||||
:marked
|
||||
In Angular 2, the `ngClass` directive works similarly.
|
||||
It includes/excludes CSS classes based on an expression.
|
||||
|
||||
In the first example, the `active` class is applied to the element if `isActive` is true.
|
||||
|
||||
We can specify multiple classes as shown in the second example.
|
||||
|
||||
Angular 2 also has **class binding**, which is good way to add or remove a single class
|
||||
as shown in the third example.
|
||||
|
||||
For more information see [Template Syntax](../guide/template-syntax.html#other-bindings).
|
||||
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### ng-click
|
||||
code-example(format="").
|
||||
<button ng-click="vm.toggleImage()">
|
||||
<button ng-click="vm.toggleImage($event)">
|
||||
:marked
|
||||
In Angular 1, the `ng-click` directive allows us to specify custom behavior when an element is clicked.
|
||||
|
||||
In the first example, when the button is clicked, the `toggleImage()` method in the controller referenced by the `vm` `controller as` alias is executed.
|
||||
|
||||
The second example demonstrates passing in the `$event` object, which provides details about the event
|
||||
to the controller.
|
||||
td
|
||||
:marked
|
||||
### bind to the `click` event
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'event-binding')(format="." )
|
||||
:marked
|
||||
The Angular 1 event-based directives do not exist in Angular 2.
|
||||
Rather, we define one-way binding from the template view to the component using **event binding**.
|
||||
|
||||
For event binding, we define the name of the target event within parenthesis and
|
||||
specify a template statement in quotes to the right of the equals. Angular 2 then
|
||||
sets up an event handler for the target event. When the event is raised, the handler
|
||||
executes the template statement.
|
||||
|
||||
In the first example, when the button is clicked, the `toggleImage()` method in the associated component is executed.
|
||||
|
||||
The second example demonstrates passing in the `$event` object, which provides details about the event
|
||||
to the component.
|
||||
|
||||
For a list of DOM events, see: https://developer.mozilla.org/en-US/docs/Web/Events.
|
||||
|
||||
For more information see [Template Syntax](../guide/template-syntax.html#event-binding).
|
||||
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### ng-controller
|
||||
code-example(format="").
|
||||
<div ng-controller="MovieListCtrl as vm">
|
||||
:marked
|
||||
In Angular 1, the `ng-controller` directive attaches a controller to the view.
|
||||
Using the `ng-controller` (or defining the controller as part of the routing) ties the
|
||||
view to the controller code associated with that view.
|
||||
td
|
||||
:marked
|
||||
### Component decorator
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.ts', 'component')(format="." )
|
||||
:marked
|
||||
In Angular 2, the template no longer specifies its associated controller.
|
||||
Rather, the component specifies its associated template as part of the component class decorator.
|
||||
|
||||
For more information see [Architecture Overview](../guide/architecture.html#component).
|
||||
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### ng-hide
|
||||
In Angular 1, the `ng-hide` directive shows or hides the associated HTML element based on
|
||||
an expression. See [ng-show](#ng-show) for more information.
|
||||
td
|
||||
:marked
|
||||
### bind to the `hidden` property
|
||||
In Angular 2, we use property binding; there is no built-in *hide* directive.
|
||||
See [ng-show](#ng-show) for more information.
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### ng-href
|
||||
code-example(format="").
|
||||
<a ng-href="angularDocsUrl">Angular Docs</a>
|
||||
:marked
|
||||
The `ng-href` directive allows Angular 1 to preprocess the `href` property so it
|
||||
can replace the binding expression with the appropriate URL before the browser
|
||||
fetches from that URL.
|
||||
|
||||
In Angular 1, the `ng-href` is often used to activate a route as part of navigation.
|
||||
code-example(format="").
|
||||
<a ng-href="#movies">Movies</a>
|
||||
:marked
|
||||
Routing is handled differently in Angular 2.
|
||||
td
|
||||
:marked
|
||||
### bind to the `href` property
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'href')(format="." )
|
||||
:marked
|
||||
In Angular 2, we use property binding; there is no built-in *href* directive.
|
||||
We place the element's `href` property in square brackets and set it to a quoted template expression.
|
||||
|
||||
For more information on property binding see [Template Syntax](../guide/template-syntax.html#property-binding).
|
||||
|
||||
In Angular 2, `href` is no longer used for routing. Routing uses `routerLink` as shown in the third example.
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'router-link')(format="." )
|
||||
:marked
|
||||
For more information on routing see [Routing & Navigation](../guide/router.html#router-link).
|
||||
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### ng-if
|
||||
code-example(format="").
|
||||
<table ng-if="movies.length">
|
||||
:marked
|
||||
In Angular 1, the `ng-if` directive removes or recreates a portion of the DOM
|
||||
based on an expression. If the expression is false, the element is removed from the DOM.
|
||||
|
||||
In this example, the `table` element is removed from the DOM unless the `movies` array has a length.
|
||||
td
|
||||
:marked
|
||||
### *ngIf
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.html', 'ngIf')(format="." )
|
||||
:marked
|
||||
The `*ngIf` directive in Angular 2 works the same as the `ng-if` directive in Angular 1,
|
||||
it removes or recreates a portion of the DOM based on an expression.
|
||||
|
||||
In this example, the `table` element is removed from the DOM unless the `movies` array has a length.
|
||||
|
||||
The (*) before `ngIf` is required in this example.
|
||||
For more information see [Structural Directives](../guide/structural-directives).
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### ng-model
|
||||
code-example(format="").
|
||||
<input ng-model="vm.favoriteHero"/>
|
||||
:marked
|
||||
In Angular 1, the `ng-model` directive binds a form control to a property in the controller associated with the template.
|
||||
This provides **two-way binding** whereby any changes made to the value in the view is synchronized with the model and
|
||||
any changes to the model are synchronized with the value in the view.
|
||||
td
|
||||
:marked
|
||||
### ngModel
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.html', 'ngModel')(format="." )
|
||||
:marked
|
||||
In Angular 2, **two-way binding** is denoted with [()], descriptively referred to as a "banana in a box".
|
||||
This syntax is a short-cut for defining both property binding (from the component to the view)
|
||||
and event binding (from the view to the component), thereby giving us two-way binding.
|
||||
|
||||
For more information on two-way binding with ngModel see [Template Syntax](../guide/template-syntax.html#ngModel).
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### ng-repeat
|
||||
code-example(format="").
|
||||
<tr ng-repeat="movie in vm.movies">
|
||||
:marked
|
||||
In Angular 1, the `ng-repeat` directive repeats the associated DOM element
|
||||
for each item from the specified collection.
|
||||
|
||||
In this example, the table row (`tr`) element is repeated for each movie object in the collection of movies.
|
||||
td
|
||||
:marked
|
||||
### *ngFor
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.html', 'ngFor')(format="." )
|
||||
:marked
|
||||
The `*ngFor` directive in Angular 2 is similar to the `ng-repeat` directive in Angular 1.
|
||||
It repeats the associated DOM element for each item from the specified collection.
|
||||
More accurately, it turns the defined element (`tr` in this example) and its contents into a template and
|
||||
uses that template to instantiate a view for each item in the list.
|
||||
|
||||
Notice the other syntax differences:
|
||||
The (*) before `ngFor` is required;
|
||||
the (#) identifies `movie` as a local variable;
|
||||
the list preposition is `of`, not `in`.
|
||||
|
||||
For more information see [Structural Directives](../guide/structural-directives).
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### ng-show
|
||||
code-example(format="").
|
||||
<h3 ng-show="vm.favoriteHero">
|
||||
Your favorite hero is: {{vm.favoriteHero}}
|
||||
</h3>
|
||||
:marked
|
||||
In Angular 1, the `ng-show` directive shows or hides the associated DOM element based on
|
||||
an expression.
|
||||
|
||||
In this example, the `div` element is shown if the `favoriteHero` variable is truthy.
|
||||
td
|
||||
:marked
|
||||
### bind to the `hidden` property
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.html', 'hidden')(format="." )
|
||||
:marked
|
||||
In Angular 2, we use property binding; there is no built-in *show* directive.
|
||||
For hiding and showing elements, we bind to the HTML `hidden` property.
|
||||
|
||||
To conditionally display an element, place the element's `hidden` property in square brackets and
|
||||
set it to a quoted template expression that evaluates to the *opposite* of *show*.
|
||||
|
||||
In this example, the `div` element is hidden if the `favoriteHero` variable is not truthy.
|
||||
|
||||
For more information on property binding see [Template Syntax](../guide/template-syntax.html#property-binding).
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### ng-src
|
||||
code-example(format="").
|
||||
<img ng-src="{{movie.imageurl}}">
|
||||
:marked
|
||||
The `ng-src` directive allows Angular 1 to preprocess the `src` property so it
|
||||
can replace the binding expression with the appropriate URL before the browser
|
||||
fetches from that URL.
|
||||
td
|
||||
:marked
|
||||
### bind to the `src` property
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'src')(format="." )
|
||||
:marked
|
||||
In Angular 2, we use property binding; there is no built-in *src* directive.
|
||||
We place the `src` property in square brackets and set it to a quoted template expression.
|
||||
|
||||
For more information on property binding see [Template Syntax](../guide/template-syntax.html#property-binding).
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### ng-style
|
||||
code-example(format="").
|
||||
<div ng-style="{color: colorPreference}">
|
||||
:marked
|
||||
In Angular 1, the `ng-style` directive sets a CSS style on an HTML element
|
||||
based on an expression. That expression is often a key-value control object with each
|
||||
key of the object defined as a CSS style name, and each value defined as an expression
|
||||
that evaluates to a value appropriate for the style.
|
||||
|
||||
In the example, the `color` style is set to the current value of the `colorPreference` variable.
|
||||
td
|
||||
:marked
|
||||
### ngStyle
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'ngStyle')(format="." )
|
||||
:marked
|
||||
In Angular 2, the `ngStyle` directive works similarly. It sets a CSS style on an HTML element based on an expression.
|
||||
|
||||
In the first example, the `color` style is set to the current value of the `colorPreference` variable.
|
||||
|
||||
Angular 2 also has **style binding**, which is good way to set a single style. This is shown in the second example.
|
||||
|
||||
For more information on style binding see [Template Syntax](../guide/template-syntax.html#style-binding).
|
||||
|
||||
For more information on the ngStyle directive see [Template Syntax](../guide/template-syntax.html#ngStyle).
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### ng-switch
|
||||
code-example(format="").
|
||||
<div ng-switch="vm.favoriteHero &&
|
||||
vm.checkMovieHero(vm.favoriteHero)">
|
||||
<div ng-switch-when="true">
|
||||
Excellent choice!
|
||||
</div>
|
||||
<div ng-switch-when="false">
|
||||
No movie, sorry!
|
||||
</div>
|
||||
<div ng-switch-default>
|
||||
Please enter your favorite hero.
|
||||
</div>
|
||||
</div>
|
||||
:marked
|
||||
In Angular 1, the `ng-switch` directive swaps the contents of
|
||||
an element by selecting one of the templates based on the current value of an expression.
|
||||
|
||||
In this example, if `favoriteHero` is not set, the template displays "Please enter ...".
|
||||
If the `favoriteHero` is set, it checks the movie hero by calling a controller method.
|
||||
If that method returns `true`, the template displays "Excellent choice!".
|
||||
If that methods returns `false`, the template displays "No movie, sorry!".
|
||||
td
|
||||
:marked
|
||||
### ngSwitch
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.html', 'ngSwitch')(format="." )
|
||||
:marked
|
||||
In Angular 2, the `ngSwitch` directive works similarly.
|
||||
It displays an element whose `*ngSwitchWhen` matches the current `ngSwitch` expression value.
|
||||
|
||||
In this example, if `favoriteHero` is not set, the `ngSwitch` value is `null`
|
||||
and we see the `*ngSwitchDefault` paragraph, "Please enter ...".
|
||||
If the `favoriteHero` is set, it checks the movie hero by calling a component method.
|
||||
If that method returns `true`, we see "Excellent choice!".
|
||||
If that methods returns `false`, we see "No movie, sorry!".
|
||||
|
||||
The (*) before `ngSwitchWhen` and `ngSwitchDefault` is required in this example.
|
||||
|
||||
For more information on the ngSwitch directive see [Template Syntax](../guide/template-syntax.html#ngSwitch).
|
||||
:marked
|
||||
[Back to top](#top)
|
||||
|
||||
a(id="filters-pipes")
|
||||
.l-main-section
|
||||
:marked
|
||||
## Filters / Pipes
|
||||
Angular 2 **pipes** provide formatting and transformation for data in our template, similar to Angular 1 **filters**.
|
||||
Many of the built-in filters in Angular 1 have corresponding pipes in Angular 2.
|
||||
For more information on pipes see [Pipes](../guide/pipes.html).
|
||||
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th Angular 1
|
||||
th Angular 2
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### currency
|
||||
code-example.
|
||||
<td>{{movie.price | currency}}</td>
|
||||
:marked
|
||||
Formats a number as a currency.
|
||||
td
|
||||
:marked
|
||||
### currency
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'currency')(format="." )
|
||||
:marked
|
||||
The Angular 2 `currency` pipe is similar although some of the parameters have changed.
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### date
|
||||
code-example.
|
||||
<td>{{movie.releaseDate | date}}</td>
|
||||
:marked
|
||||
Formats a date to a string based on the requested format.
|
||||
td
|
||||
:marked
|
||||
### date
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'date')(format=".")
|
||||
:marked
|
||||
The Angular 2 `date` pipe is similar. See [note](#string-dates) about string date values.
|
||||
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### filter
|
||||
code-example.
|
||||
<tr ng-repeat="movie in movieList | filter: {title:listFilter}">
|
||||
:marked
|
||||
Selects a subset of items from the defined collection based on the filter criteria.
|
||||
td
|
||||
:marked
|
||||
### none
|
||||
:marked
|
||||
There is no comparable pipe in Angular 2 for performance reasons.
|
||||
Filtering should be coded in the component.
|
||||
Consider building a custom pipe if the same filtering code
|
||||
will be reused in several templates.
|
||||
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### json
|
||||
code-example.
|
||||
<pre>{{movie | json}}</pre>
|
||||
:marked
|
||||
Converts a JavaScript object into a JSON string. This is useful for debugging.
|
||||
td
|
||||
:marked
|
||||
### json
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'json')(format=".")
|
||||
:marked
|
||||
The Angular 2 `json` pipe does the same thing.
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### limitTo
|
||||
code-example.
|
||||
<tr ng-repeat="movie in movieList | limitTo: 2">
|
||||
:marked
|
||||
Selects the defined number of items from the collection.
|
||||
td
|
||||
:marked
|
||||
### slice
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'slice')(format=".")
|
||||
:marked
|
||||
The first parameter of the `SlicePipe` is the starting index; the second is the limit.
|
||||
As in Angular 1, performance may improve if this operation is coded in the component.
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### lowercase
|
||||
code-example.
|
||||
<div>{{movie.title | lowercase}}</div>
|
||||
:marked
|
||||
Converts the string to lowercase.
|
||||
td
|
||||
:marked
|
||||
### lowercase
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'lowercase')(format=".")
|
||||
:marked
|
||||
The Angular 2 `lowercase` pipe does the same thing.
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### number
|
||||
code-example.
|
||||
<td>{{movie.starRating | number}}</td>
|
||||
:marked
|
||||
Formats a number as text.
|
||||
td
|
||||
:marked
|
||||
### number
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'number')(format=".")
|
||||
:marked
|
||||
The Angular 2 `number` pipe is similar.
|
||||
It provides more functionality when defining
|
||||
the decimal places as shown in the second example above.
|
||||
|
||||
Angular 2 also has a `percent` pipe which formats a number as a local percentage
|
||||
as shown in the third example.
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### orderBy
|
||||
code-example.
|
||||
<tr ng-repeat="movie in movieList | orderBy : 'title'">
|
||||
:marked
|
||||
Orders the collection as specified by the expression.
|
||||
In this example, the movieList is ordered by the movie title.
|
||||
td
|
||||
:marked
|
||||
### none
|
||||
There is no comparable pipe in Angular 2 for performance reasons.
|
||||
Ordering/sorting the results should be coded in the component.
|
||||
Consider building a custom pipe if the same ordering/sorting code
|
||||
will be reused in several templates.
|
||||
:marked
|
||||
[Back to top](#top)
|
||||
|
||||
a(id="controllers-components")
|
||||
.l-main-section
|
||||
:marked
|
||||
## Controllers / Components
|
||||
In Angular 1, we write the code that provides the model and the methods for the view in a **controller**.
|
||||
In Angular 2, we build a **component**.
|
||||
|
||||
Because much of our Angular 1 code is in JavaScript, JavaScript code is shown in the Angular 1 column.
|
||||
The Angular 2 code is shown using TypeScript.
|
||||
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th Angular 1
|
||||
th Angular 2
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### IIFE
|
||||
code-example.
|
||||
(function () {
|
||||
}());
|
||||
:marked
|
||||
In Angular 1, we often defined an immediately invoked function expression (or IIFE) around our controller code.
|
||||
This kept our controller code out of the global namespace.
|
||||
td
|
||||
:marked
|
||||
### none
|
||||
We don't need to worry about this in Angular 2 because we use ES 2015 modules
|
||||
and modules handle the namespacing for us.
|
||||
|
||||
For more information on modules see [Architecture Overview](../guide/architecture.html#module).
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Angular modules
|
||||
code-example.
|
||||
angular.module("movieHunter", ["ngRoute"]);
|
||||
:marked
|
||||
In Angular 1, we define an Angular module, which keeps track of our
|
||||
controllers, services, and other code. The second argument defines the list
|
||||
of other modules that this module depends upon.
|
||||
td
|
||||
:marked
|
||||
### import
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.ts', 'import')(format=".")
|
||||
:marked
|
||||
Angular 2 does not have its own module system. Instead we use ES 2015 modules.
|
||||
ES 2015 modules are file based, so each code file is its own module.
|
||||
|
||||
We `import` what we need from the module files.
|
||||
|
||||
For more information on modules see [Architecture Overview](../guide/architecture.html#module).
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Controller registration
|
||||
code-example.
|
||||
angular
|
||||
.module("movieHunter")
|
||||
.controller("MovieListCtrl",
|
||||
["movieService",
|
||||
MovieListCtrl]);
|
||||
:marked
|
||||
In Angular 1, we have code in each controller that looks up an appropriate Angular module
|
||||
and registers the controller with that module.
|
||||
|
||||
The first argument is the controller name. The second argument defines the string names of
|
||||
all dependencies injected into this controller, and a reference to the controller function.
|
||||
td
|
||||
:marked
|
||||
### Component Decorator
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.ts', 'component')(format=".")
|
||||
:marked
|
||||
In Angular 2, we add a decorator to the component class to provide any required metadata.
|
||||
The Component decorator declares that the class is a component and provides metadata about
|
||||
that component, such as its selector (or tag) and its template.
|
||||
|
||||
This is how we associate a template with code, which is defined in the component class.
|
||||
|
||||
For more information on components see [Architecture Overview](../guide/architecture.html#component).
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Controller function
|
||||
code-example.
|
||||
function MovieListCtrl(movieService) {
|
||||
}
|
||||
:marked
|
||||
In Angular 1, we write the code for the model and methods in a controller function.
|
||||
td
|
||||
:marked
|
||||
### Component class
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.ts', 'class')(format=".")
|
||||
:marked
|
||||
In Angular 2, we create a component class.
|
||||
|
||||
NOTE: If you are using TypeScript with Angular 1 then the only difference here is
|
||||
that the component class must be exported using the `export` keyword.
|
||||
|
||||
For more information on components see [Architecture Overview](../guide/architecture.html#component).
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Dependency injection
|
||||
code-example.
|
||||
MovieListCtrl.$inject = ['MovieService'];
|
||||
function MovieListCtrl(movieService) {
|
||||
}
|
||||
:marked
|
||||
In Angular 1, we pass in any dependencies as controller function arguments.
|
||||
In this example, we inject a `MovieService`.
|
||||
|
||||
We also guard against minification problems by telling Angular explicitly
|
||||
that it should inject an instance of the `MovieService` in the first parameter.
|
||||
td
|
||||
:marked
|
||||
### Dependency injection
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.ts', 'di')(format=".")
|
||||
:marked
|
||||
In Angular 2, we pass in dependencies as arguments to the component class constructor.
|
||||
In this example, we inject a `MovieService`.
|
||||
The first parameter's TypeScript type tells Angular what to inject even after minification.
|
||||
|
||||
For more information on dependency injection see [Architecture Overview](../guide/architecture.html#dependency-injection).
|
||||
:marked
|
||||
[Back to top](#top)
|
||||
|
||||
a(id="style-sheets")
|
||||
.l-main-section
|
||||
:marked
|
||||
## Style Sheets
|
||||
Style sheets give our application a nice look.
|
||||
In Angular 1, we specify the style sheets for our entire application.
|
||||
As the application grows over time, the styles for the many parts of the application
|
||||
are merged, which can cause unexpected results.
|
||||
In Angular 2, we can still define style sheets for our entire application. But now we can
|
||||
also encapculate a style sheet within a specific component.
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th Angular 1
|
||||
th Angular 2
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### Link tag
|
||||
code-example.
|
||||
<link href="styles.css" rel="stylesheet" />
|
||||
:marked
|
||||
In Angular 1, we use a `link` tag in the head section of our `index.html` file
|
||||
to define the styles for our application.
|
||||
td
|
||||
:marked
|
||||
### Link tag
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/index.html', 'style')(format=".")
|
||||
:marked
|
||||
In Angular 2, we can continue to use the link tag to define the styles for our application in the `index.html` file.
|
||||
But we can now also encapsulate styles for our components.
|
||||
:marked
|
||||
### StyleUrls
|
||||
In Angular 2, we can use the `styles` or `styleUrls` property of the `@Component` metadata to define
|
||||
a style sheet for a particular component.
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.ts', 'style-url')(format=".")
|
||||
:marked
|
||||
This allows us to set appropriate styles for individual components that won’t leak into
|
||||
other parts of the application.
|
||||
:marked
|
||||
[Back to top](#top)
|
||||
|
||||
a(id="string-dates")
|
||||
.l-main-section
|
||||
:marked
|
||||
## Appendix: String dates
|
||||
|
||||
Currently the Angular 2 `date` pipe does not process string dates such as
|
||||
"2015-12-19T00:00:00".
|
||||
|
||||
As a work around, subclass the Angular `DatePipe` with a version that can convert strings
|
||||
and substitute that pipe in the HTML:
|
||||
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/date.pipe.ts', 'date-pipe', 'date.pipe.ts')(format=".")
|
||||
:marked
|
||||
Then import and declare that pipe in the `@Component` metadata `pipes` array:
|
||||
:marked
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.ts', 'date-pipe')(format=".")
|
||||
|
||||
:marked
|
||||
[Back to top](#top)
|
Loading…
Reference in New Issue