Merge remote-tracking branch 'origin/master'

# Conflicts:
#	public/docs/ts/latest/guide/_data.json
This commit is contained in:
Zhicheng Wang 2016-06-19 10:17:03 +08:00
commit 0aa207bbac
113 changed files with 2717 additions and 382 deletions

BIN
public/docs/ImageGuide.pdf Normal file

Binary file not shown.

View File

@ -1,6 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "es5", "target": "es6",
"module": "commonjs", "module": "commonjs",
"moduleResolution": "node", "moduleResolution": "node",
"sourceMap": true, "sourceMap": true,

View File

@ -1,9 +1,8 @@
{ {
"globalDependencies": { "globalDependencies": {
"angular-protractor": "registry:dt/angular-protractor#1.5.0+20160425143459", "angular-protractor": "registry:dt/angular-protractor#1.5.0+20160425143459",
"core-js": "registry:dt/core-js#0.0.0+20160317120654",
"jasmine": "registry:dt/jasmine#2.2.0+20160505161446", "jasmine": "registry:dt/jasmine#2.2.0+20160505161446",
"node": "registry:dt/node#4.0.0+20160509154515", "node": "registry:dt/node#6.0.0+20160613154055",
"selenium-webdriver": "registry:dt/selenium-webdriver#2.44.0+20160317120654" "selenium-webdriver": "registry:dt/selenium-webdriver#2.44.0+20160317120654"
} }
} }

View File

@ -1,4 +1,5 @@
/// <reference path='../_protractor/e2e.d.ts' /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
/** /**
* The tests here basically just checking that the end styles * The tests here basically just checking that the end styles
* of each animation are in effect. * of each animation are in effect.
@ -29,7 +30,7 @@ describe('Animation Tests', () => {
}); });
it('animates between active and inactive', () => { it('animates between active and inactive', () => {
addHero(); addInactiveHero();
let li = host.element(by.css('li')); let li = host.element(by.css('li'));
@ -58,7 +59,7 @@ describe('Animation Tests', () => {
}); });
it('are not kept after animation', () => { it('are not kept after animation', () => {
addHero(); addInactiveHero();
let li = host.element(by.css('li')); let li = host.element(by.css('li'));
@ -79,7 +80,7 @@ describe('Animation Tests', () => {
}); });
it('animates between active and inactive', () => { it('animates between active and inactive', () => {
addHero(); addInactiveHero();
let li = host.element(by.css('li')); let li = host.element(by.css('li'));
@ -108,7 +109,7 @@ describe('Animation Tests', () => {
}); });
it('animates between active and inactive', () => { it('animates between active and inactive', () => {
addHero(); addInactiveHero();
let li = host.element(by.css('li')); let li = host.element(by.css('li'));
@ -137,7 +138,7 @@ describe('Animation Tests', () => {
}); });
it('adds and removes element', () => { it('adds and removes element', () => {
addHero(); addInactiveHero();
let li = host.element(by.css('li')); let li = host.element(by.css('li'));
expect(li.getCssValue('transform')).toMatch(NO_TRANSFORM_MATRIX_REGEX); expect(li.getCssValue('transform')).toMatch(NO_TRANSFORM_MATRIX_REGEX);
@ -157,7 +158,7 @@ describe('Animation Tests', () => {
}); });
it('adds and removes and animates between active and inactive', () => { it('adds and removes and animates between active and inactive', () => {
addHero(); addInactiveHero();
let li = host.element(by.css('li')); let li = host.element(by.css('li'));
@ -186,7 +187,7 @@ describe('Animation Tests', () => {
}); });
it('adds and removes element', () => { it('adds and removes element', () => {
addHero(); addInactiveHero();
let li = host.element(by.css('li')); let li = host.element(by.css('li'));
expect(li.getCssValue('height')).toBe('50px'); expect(li.getCssValue('height')).toBe('50px');
@ -206,7 +207,7 @@ describe('Animation Tests', () => {
}); });
it('adds and removes element', () => { it('adds and removes element', () => {
addHero(); addInactiveHero();
let li = host.element(by.css('li')); let li = host.element(by.css('li'));
expect(li.getCssValue('transform')).toMatch(NO_TRANSFORM_MATRIX_REGEX); expect(li.getCssValue('transform')).toMatch(NO_TRANSFORM_MATRIX_REGEX);
@ -227,7 +228,7 @@ describe('Animation Tests', () => {
}); });
it('adds and removes element', () => { it('adds and removes element', () => {
addHero(); addInactiveHero();
let li = host.element(by.css('li')); let li = host.element(by.css('li'));
expect(li.getCssValue('transform')).toMatch(NO_TRANSFORM_MATRIX_REGEX); expect(li.getCssValue('transform')).toMatch(NO_TRANSFORM_MATRIX_REGEX);
@ -248,7 +249,7 @@ describe('Animation Tests', () => {
}); });
it('adds and removes element', () => { it('adds and removes element', () => {
addHero(); addInactiveHero();
let li = host.element(by.css('li')); let li = host.element(by.css('li'));
expect(li.getCssValue('transform')).toMatch(NO_TRANSFORM_MATRIX_REGEX); expect(li.getCssValue('transform')).toMatch(NO_TRANSFORM_MATRIX_REGEX);
@ -260,8 +261,41 @@ describe('Animation Tests', () => {
}); });
function addHero() { describe('adding active heroes', () => {
element(by.buttonText('Add hero')).click();
let host: protractor.ElementFinder;
beforeEach(() => {
host = element(by.css('hero-list-basic'));
});
it('animates between active and inactive', () => {
addActiveHero();
let li = host.element(by.css('li'));
expect(getScaleX(li)).toBe(1.1);
expect(li.getCssValue('backgroundColor')).toBe(ACTIVE_COLOR);
li.click();
browser.driver.sleep(300);
expect(getScaleX(li)).toBe(1.0);
expect(li.getCssValue('backgroundColor')).toBe(INACTIVE_COLOR);
li.click();
browser.driver.sleep(300);
expect(getScaleX(li)).toBe(1.1);
expect(li.getCssValue('backgroundColor')).toBe(ACTIVE_COLOR);
});
});
function addActiveHero() {
element(by.buttonText('Add active hero')).click();
browser.driver.sleep(500);
}
function addInactiveHero() {
element(by.buttonText('Add inactive hero')).click();
browser.driver.sleep(500); browser.driver.sleep(500);
} }
@ -274,7 +308,9 @@ describe('Animation Tests', () => {
return protractor.promise.all([ return protractor.promise.all([
getBoundingClientWidth(el), getBoundingClientWidth(el),
getOffsetWidth(el) getOffsetWidth(el)
]).then(function([clientWidth, offsetWidth]) { ]).then(function(promiseResolutions) {
let clientWidth = promiseResolutions[0];
let offsetWidth = promiseResolutions[1];
return clientWidth / offsetWidth; return clientWidth / offsetWidth;
}); });
} }

View File

@ -16,7 +16,8 @@ import { HeroListTimingsComponent } from './hero-list-timings.component';
selector: 'hero-team-builder', selector: 'hero-team-builder',
template: ` template: `
<div class="buttons"> <div class="buttons">
<button [disabled]="!heroes.canAdd()" (click)="heroes.add()">Add hero</button> <button [disabled]="!heroes.canAdd()" (click)="heroes.addInactive()">Add inactive hero</button>
<button [disabled]="!heroes.canAdd()" (click)="heroes.addActive()">Add active hero</button>
<button [disabled]="!heroes.canRemove()" (click)="heroes.remove()">Remove hero</button> <button [disabled]="!heroes.canRemove()" (click)="heroes.remove()">Remove hero</button>
</div> </div>
<div class="columns"> <div class="columns">

View File

@ -11,19 +11,17 @@ class Hero {
} }
let ALL_HEROES = [ let ALL_HEROES = [
'Wolverine', 'Windstorm',
'Magneto', 'RubberMan',
'Emma Frost', 'Bombasto',
'Thing', 'Magneta',
'Kitty Pryde', 'Dynama',
'Nightcrawler', 'Narco',
'Juggernaut', 'Celeritas',
'Beast', 'Dr IQ',
'Captain America', 'Magma',
'Spider-Man', 'Tornado',
'Puck', 'Mr. Nice'
'Alex Wilder',
'Doctor Strange'
].map(name => new Hero(name)); ].map(name => new Hero(name));
@Injectable() @Injectable()
@ -43,8 +41,16 @@ export class Heroes implements Iterable<Hero> {
return this.currentHeroes.length > 0; return this.currentHeroes.length > 0;
} }
add() { addActive() {
this.currentHeroes.push(ALL_HEROES[this.currentHeroes.length]); let hero = ALL_HEROES[this.currentHeroes.length];
hero.state = 'active';
this.currentHeroes.push(hero);
}
addInactive() {
let hero = ALL_HEROES[this.currentHeroes.length];
hero.state = 'inactive';
this.currentHeroes.push(hero);
} }
remove() { remove() {

View File

@ -1,4 +1,5 @@
/// <reference path='../_protractor/e2e.d.ts' /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Architecture', function () { describe('Architecture', function () {
let title = 'Hero List'; let title = 'Hero List';

View File

@ -1,4 +1,5 @@
/// <reference path='../_protractor/e2e.d.ts' /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Attribute directives', function () { describe('Attribute directives', function () {
let _title = 'My First Attribute Directive'; let _title = 'My First Attribute Directive';

View File

@ -1,4 +1,5 @@
/// <reference path='../_protractor/e2e.d.ts' /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Angular 1 to 2 Quick Reference Tests', function () { describe('Angular 1 to 2 Quick Reference Tests', function () {
beforeAll(function () { beforeAll(function () {

View File

@ -1,4 +1,5 @@
/// <reference path='../_protractor/e2e.d.ts' /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Component Communication Cookbook Tests', function () { describe('Component Communication Cookbook Tests', function () {

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Cookbook: component-relative paths', function () { describe('Cookbook: component-relative paths', function () {
interface Page { interface Page {

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Dependency Injection Cookbook', function () { describe('Dependency Injection Cookbook', function () {
beforeAll(function () { beforeAll(function () {

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
/* tslint:disable:quotemark */ /* tslint:disable:quotemark */
describe('Dynamic Form', function () { describe('Dynamic Form', function () {

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
// gulp run-e2e-tests --filter=cb-set-document-title // gulp run-e2e-tests --filter=cb-set-document-title
describe('Set Document Title', function () { describe('Set Document Title', function () {

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('TypeScript to Javascript tests', function () { describe('TypeScript to Javascript tests', function () {
beforeAll(function () { beforeAll(function () {

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('cli-quickstart App', () => { describe('cli-quickstart App', () => {
beforeEach(() => { beforeEach(() => {
return browser.get('/'); return browser.get('/');

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Component Style Tests', function () { describe('Component Style Tests', function () {
beforeAll(function () { beforeAll(function () {

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Dependency Injection Tests', function () { describe('Dependency Injection Tests', function () {

View File

@ -1,4 +1,5 @@
/// <reference path='../_protractor/e2e.d.ts' /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Displaying Data Tests', function () { describe('Displaying Data Tests', function () {
let _title = 'Tour of Heroes'; let _title = 'Tour of Heroes';
let _defaultHero = 'Windstorm'; let _defaultHero = 'Windstorm';

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describeIf(browser.appIsTs || browser.appIsJs, 'Forms Tests', function () { describeIf(browser.appIsTs || browser.appIsJs, 'Forms Tests', function () {
beforeEach(function () { beforeEach(function () {

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Hierarchical dependency injection', function () { describe('Hierarchical dependency injection', function () {
beforeEach(function () { beforeEach(function () {

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Homepage Hello World', function () { describe('Homepage Hello World', function () {
beforeAll(function () { beforeAll(function () {

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Homepage Tabs', function () { describe('Homepage Tabs', function () {
beforeAll(function () { beforeAll(function () {

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Homepage Todo', function () { describe('Homepage Todo', function () {
beforeAll(function () { beforeAll(function () {

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Lifecycle hooks', function () { describe('Lifecycle hooks', function () {
beforeAll(function () { beforeAll(function () {

View File

@ -45,7 +45,7 @@
"devDependencies": { "devDependencies": {
"angular-cli": "^1.0.0-beta.5", "angular-cli": "^1.0.0-beta.5",
"canonical-path": "0.0.2", "canonical-path": "0.0.2",
"concurrently": "^2.0.0", "concurrently": "^2.1.0",
"css-loader": "^0.23.1", "css-loader": "^0.23.1",
"extract-text-webpack-plugin": "^1.0.1", "extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.8.5", "file-loader": "^0.8.5",
@ -62,7 +62,7 @@
"karma-sourcemap-loader": "^0.3.7", "karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^1.7.0", "karma-webpack": "^1.7.0",
"lite-server": "^2.2.0", "lite-server": "^2.2.0",
"lodash": "^4.11.1", "lodash": "^4.13.1",
"null-loader": "^0.1.1", "null-loader": "^0.1.1",
"phantomjs-prebuilt": "^2.1.7", "phantomjs-prebuilt": "^2.1.7",
"protractor": "^3.3.0", "protractor": "^3.3.0",
@ -71,7 +71,7 @@
"style-loader": "^0.13.1", "style-loader": "^0.13.1",
"ts-loader": "^0.8.2", "ts-loader": "^0.8.2",
"ts-node": "^0.7.3", "ts-node": "^0.7.3",
"typescript": "^1.8.10", "typescript": "^1.9.0-dev.20160409",
"typings": "^1.0.4", "typings": "^1.0.4",
"webpack": "^1.13.0", "webpack": "^1.13.0",
"webpack-dev-server": "^1.14.1", "webpack-dev-server": "^1.14.1",

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Pipes', function () { describe('Pipes', function () {
beforeAll(function () { beforeAll(function () {

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('QuickStart E2E Tests', function () { describe('QuickStart E2E Tests', function () {
let expectedMsg = 'My First Angular 2 App'; let expectedMsg = 'My First Angular 2 App';

View File

@ -2,6 +2,6 @@
"globalDependencies": { "globalDependencies": {
"core-js": "registry:dt/core-js#0.0.0+20160317120654", "core-js": "registry:dt/core-js#0.0.0+20160317120654",
"jasmine": "registry:dt/jasmine#2.2.0+20160505161446", "jasmine": "registry:dt/jasmine#2.2.0+20160505161446",
"node": "registry:dt/node#4.0.0+20160509154515" "node": "registry:dt/node#6.0.0+20160613154055"
} }
} }

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Router', function () { describe('Router', function () {
beforeAll(function () { beforeAll(function () {

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Router', function () { describe('Router', function () {
beforeAll(function () { beforeAll(function () {

View File

@ -1,16 +1,14 @@
/* First version */ /* First version */
// #docplaster // #docplaster
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { ROUTER_DIRECTIVES, Routes } from '@angular/router'; // #docregion import-router
import { ROUTER_DIRECTIVES } from '@angular/router';
import { CrisisListComponent } from './crisis-list.component'; // #enddocregion import-router
import { HeroListComponent } from './hero-list.component';
@Component({ @Component({
selector: 'my-app', selector: 'my-app',
// #docregion template // #docregion template
template: ` template: `
<h1>Component Router</h1> <h1>Component Router</h1>
<nav> <nav>
@ -19,24 +17,10 @@ import { HeroListComponent } from './hero-list.component';
</nav> </nav>
<router-outlet></router-outlet> <router-outlet></router-outlet>
`, `,
// #enddocregion template // #enddocregion template
// #docregion directives
directives: [ROUTER_DIRECTIVES] directives: [ROUTER_DIRECTIVES]
// #enddocregion directives
}) })
// #enddocregion
/*
// #docregion route-config
@Component({ ... })
// #enddocregion route-config
*/
// #docregion
// #docregion route-config
@Routes([
// #docregion route-defs
{path: '/crisis-center', component: CrisisListComponent},
{path: '/heroes', component: HeroListComponent},
{path: '*', component: CrisisListComponent}
// #enddocregion route-defs
])
export class AppComponent { } export class AppComponent { }
// #enddocregion route-config
// #enddocregion

View File

@ -2,10 +2,9 @@
// #docplaster // #docplaster
// #docregion // #docregion
import { Component, OnInit } from '@angular/core'; import { Component } from '@angular/core';
import { Router, ROUTER_DIRECTIVES, Routes } from '@angular/router'; import { Router, ROUTER_DIRECTIVES } from '@angular/router';
import { CrisisListComponent } from './crisis-list.component';
// #enddocregion // #enddocregion
/* /*
// Apparent Milestone 2 imports // Apparent Milestone 2 imports
@ -18,8 +17,6 @@ import { CrisisListComponent } from './crisis-list.component';
// #enddocregion // #enddocregion
*/ */
// Actual Milestone 2 imports // Actual Milestone 2 imports
import { HeroDetailComponent } from './heroes/hero-detail.component.1';
import { HeroListComponent } from './heroes/hero-list.component.1';
import { HeroService } from './heroes/hero.service'; import { HeroService } from './heroes/hero.service';
// #docregion // #docregion
@ -37,28 +34,7 @@ import { HeroService } from './heroes/hero.service';
directives: [ROUTER_DIRECTIVES] directives: [ROUTER_DIRECTIVES]
}) })
// #enddocregion // #enddocregion
/* export class AppComponent {
// #docregion route-config
@Component({ ... })
// #enddocregion route-config
*/
// #docregion
// #docregion route-config
@Routes([
// #docregion route-defs
{path: '/crisis-center', component: CrisisListComponent},
{path: '/heroes', component: HeroListComponent},
// #docregion hero-detail-route
{path: '/hero/:id', component: HeroDetailComponent}
// #enddocregion hero-detail-route
// #enddocregion route-defs
])
export class AppComponent implements OnInit {
constructor(private router: Router) {}
ngOnInit() {
this.router.navigate(['/crisis-center']);
}
} }
// #enddocregion route-config // #enddocregion route-config
// #enddocregion // #enddocregion

View File

@ -1,13 +1,8 @@
/* tslint:disable:no-unused-variable */ /* tslint:disable:no-unused-variable */
// #docplaster // #docplaster
import { Component, OnInit } from '@angular/core'; import { Component } from '@angular/core';
import { Router, ROUTER_DIRECTIVES, Routes } from '@angular/router'; import { Router, ROUTER_DIRECTIVES } from '@angular/router';
import { CrisisCenterComponent } from './crisis-center/crisis-center.component.1';
import { HeroDetailComponent } from './heroes/hero-detail.component.1';
import { HeroListComponent } from './heroes/hero-list.component.1';
import { DialogService } from './dialog.service';
import { HeroService } from './heroes/hero.service'; import { HeroService } from './heroes/hero.service';
@Component({ @Component({
@ -41,23 +36,14 @@ import { HeroService } from './heroes/hero.service';
<h1 class="title">Component Router</h1> <h1 class="title">Component Router</h1>
<nav> <nav>
<a [routerLink]="['/crisis-center']">Crisis Center</a> <a [routerLink]="['/crisis-center']">Crisis Center</a>
<a [routerLink]="['/crisis-center', 1]">Dragon Crisis</a> <a [routerLink]="['/crisis-center/1']">Dragon Crisis</a>
<a [routerLink]="['/crisis-center', 2]">Shark Crisis</a> <a [routerLink]="['/crisis-center/2']">Shark Crisis</a>
</nav> </nav>
<router-outlet></router-outlet> <router-outlet></router-outlet>
`, `,
// #enddocregion template // #enddocregion template
providers: [DialogService, HeroService], providers: [HeroService],
directives: [ROUTER_DIRECTIVES] directives: [ROUTER_DIRECTIVES]
}) })
@Routes([ export class AppComponent {
{path: '/crisis-center', component: CrisisCenterComponent},
{path: '*', component: CrisisCenterComponent}
])
export class AppComponent implements OnInit {
constructor(private router: Router) {}
ngOnInit() {
this.router.navigate(['/crisis-center']);
}
} }

View File

@ -0,0 +1,28 @@
// #docregion
import { Component } from '@angular/core';
import { ROUTER_DIRECTIVES } from '@angular/router';
import { DialogService } from './dialog.service';
import { HeroService } from './heroes/hero.service';
@Component({
selector: 'my-app',
// #docregion template
template: `
<h1 class="title">Component Router</h1>
<nav>
<a [routerLink]="['/crisis-center']">Crisis Center</a>
<a [routerLink]="['/heroes']">Heroes</a>
<a [routerLink]="['/crisis-center/admin']">Crisis Admin</a>
</nav>
<router-outlet></router-outlet>
`,
// #enddocregion template
providers: [
HeroService,
DialogService
],
directives: [ROUTER_DIRECTIVES]
})
export class AppComponent {
}

View File

@ -0,0 +1,42 @@
// #docplaster
// #docregion
import { Component } from '@angular/core';
import { provideRouter, ROUTER_DIRECTIVES } from '@angular/router';
import { routes } from './app.routes';
// #docregion can-deactivate-guard
import { CanDeactivateGuard } from './interfaces';
// #enddocregion can-deactivate-guard
import { DialogService } from './dialog.service';
import { HeroService } from './heroes/hero.service';
// Add these symbols to override the `LocationStrategy`
import { LocationStrategy,
HashLocationStrategy } from '@angular/common';
@Component({
selector: 'my-app',
// #docregion template
template: `
<h1 class="title">Component Router</h1>
<nav>
<a [routerLink]="['/crisis-center']">Crisis Center</a>
<a [routerLink]="['/heroes']">Heroes</a>
</nav>
<router-outlet></router-outlet>
`,
// #enddocregion template
providers: [
HeroService,
DialogService,
provideRouter(routes),
CanDeactivateGuard,
{ provide: LocationStrategy,
useClass: HashLocationStrategy } // .../#/crisis-center/
],
directives: [ROUTER_DIRECTIVES]
})
export class AppComponent {
}

View File

@ -1,41 +1,30 @@
// #docplaster // #docplaster
// #docregion // #docregion
import { Component, OnInit } from '@angular/core'; import { Component } from '@angular/core';
import { Routes, Router, ROUTER_DIRECTIVES } from '@angular/router'; import { ROUTER_DIRECTIVES } from '@angular/router';
import { CrisisCenterComponent } from './crisis-center/crisis-center.component';
import { HeroListComponent } from './heroes/hero-list.component';
import { HeroDetailComponent } from './heroes/hero-detail.component';
import { DialogService } from './dialog.service'; import { DialogService } from './dialog.service';
import { HeroService } from './heroes/hero.service'; import { HeroService } from './heroes/hero.service';
@Component({ @Component({
selector: 'my-app', selector: 'my-app',
// #docregion template // #docregion template
template: ` template: `
<h1 class="title">Component Router</h1> <h1 class="title">Component Router</h1>
<nav> <nav>
<a [routerLink]="['/crisis-center']">Crisis Center</a> <a [routerLink]="['/crisis-center']">Crisis Center</a>
<a [routerLink]="['/heroes']">Heroes</a> <a [routerLink]="['/heroes']">Heroes</a>
<a [routerLink]="['/crisis-center/admin']">Crisis Admin</a>
<a [routerLink]="['/login']">Login</a>
</nav> </nav>
<router-outlet></router-outlet> <router-outlet></router-outlet>
`, `,
// #enddocregion template // #enddocregion template
providers: [DialogService, HeroService], providers: [
HeroService,
DialogService
],
directives: [ROUTER_DIRECTIVES] directives: [ROUTER_DIRECTIVES]
}) })
// #docregion routes export class AppComponent {
@Routes([
{path: '/crisis-center', component: CrisisCenterComponent},
{path: '/heroes', component: HeroListComponent},
{path: '/hero/:id', component: HeroDetailComponent},
])
// #enddocregion routes
export class AppComponent implements OnInit {
constructor(private router: Router) {}
ngOnInit() {
this.router.navigate(['/crisis-center']);
}
} }

View File

@ -0,0 +1,31 @@
// #docplaster
// #docregion
// #docregion route-config
import { provideRouter, RouterConfig } from '@angular/router';
// #enddocregion route-config
// #enddocregion
// #docregion base-routes
import { HeroListComponent } from './hero-list.component';
import { CrisisCenterComponent } from './crisis-center/crisis-center.component';
import { HeroDetailComponent } from './heroes/hero-detail.component';
// #enddocregion base-routes
// #docregion
// #docregion route-config
export const routes: RouterConfig = [
// #docregion route-defs
{ path: '/crisis-center', component: CrisisCenterComponent },
{ path: '/heroes', component: HeroListComponent },
// #enddocregion route-defs
// #docregion hero-detail-route
{ path: '/hero/:id', component: HeroDetailComponent }
// #enddocregion hero-detail-route
];
export const APP_ROUTER_PROVIDERS = [
provideRouter(routes)
];
// #enddocregion route-config
// #enddocregion

View File

@ -0,0 +1,19 @@
// #docplaster
// #docregion
// #docregion route-config
import { provideRouter, RouterConfig } from '@angular/router';
// #enddocregion route-config
import { CrisisListComponent } from './crisis-list.component';
import { HeroListComponent } from './hero-list.component';
// #docregion route-config
export const routes: RouterConfig = [
{ path: '/crisis-center', component: CrisisListComponent },
{ path: '/heroes', component: HeroListComponent }
];
export const APP_ROUTER_PROVIDERS = [
provideRouter(routes)
];
// #enddocregion route-config

View File

@ -0,0 +1,15 @@
// #docplaster
// #docregion
import { provideRouter } from '@angular/router';
import { CrisisListComponent } from './crisis-center/crisis-list.component';
import { HeroesRoutes } from './heroes/heroes.routes';
export const routes = [
...HeroesRoutes,
{ path: '/crisis-center', component: CrisisListComponent }
];
export const APP_ROUTER_PROVIDERS = [
provideRouter(routes)
];

View File

@ -0,0 +1,14 @@
// #docregion
import { provideRouter, RouterConfig } from '@angular/router';
import { CrisisCenterRoutes } from './crisis-center/crisis-center.routes';
import { HeroesRoutes } from './heroes/heroes.routes';
export const routes: RouterConfig = [
...HeroesRoutes,
...CrisisCenterRoutes
];
export const APP_ROUTER_PROVIDERS = [
provideRouter(routes)
];

View File

@ -0,0 +1,19 @@
// #docregion
import { provideRouter, RouterConfig } from '@angular/router';
import { CrisisCenterRoutes } from './crisis-center/crisis-center.routes';
import { HeroesRoutes } from './heroes/heroes.routes';
import { LoginRoutes,
AUTH_PROVIDERS } from './login.routes';
export const routes: RouterConfig = [
...HeroesRoutes,
...LoginRoutes,
...CrisisCenterRoutes
];
export const APP_ROUTER_PROVIDERS = [
provideRouter(routes),
AUTH_PROVIDERS
];

View File

@ -0,0 +1,22 @@
// #docregion
import { provideRouter, RouterConfig } from '@angular/router';
import { CrisisCenterRoutes } from './crisis-center/crisis-center.routes';
import { HeroesRoutes } from './heroes/heroes.routes';
import { LoginRoutes,
AUTH_PROVIDERS } from './login.routes';
import { CanDeactivateGuard } from './interfaces';
export const routes: RouterConfig = [
...HeroesRoutes,
...LoginRoutes,
...CrisisCenterRoutes
];
export const APP_ROUTER_PROVIDERS = [
provideRouter(routes),
AUTH_PROVIDERS,
CanDeactivateGuard
];

View File

@ -0,0 +1,9 @@
// #docregion
import { CanActivate } from '@angular/router';
export class AuthGuard implements CanActivate {
canActivate() {
console.log('AuthGuard#canActivate called');
return true;
}
}

View File

@ -0,0 +1,22 @@
// #docregion
import { Injectable } from '@angular/core';
import { CanActivate,
Router,
ActivatedRouteSnapshot,
RouterStateSnapshot } from '@angular/router';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(
// Not using but worth knowing about
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
) {
if (this.authService.isLoggedIn) { return true; }
this.router.navigate(['/login']);
return false;
}
}

View File

@ -0,0 +1,20 @@
// #docregion
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/delay';
@Injectable()
export class AuthService {
isLoggedIn: boolean = false;
login() {
return Observable.of(true).delay(1000).do(val => this.isLoggedIn = true);
}
logout() {
this.isLoggedIn = false;
}
}

View File

@ -0,0 +1,13 @@
// #docregion
import { Component } from '@angular/core';
import { ROUTER_DIRECTIVES } from '@angular/router';
@Component({
template: `
<h3>CRISIS ADMINISTRATION</h3>
<p>Manage your crises here</p>
`,
directives: [ROUTER_DIRECTIVES]
})
export class CrisisAdminComponent { }

View File

@ -1,8 +1,6 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { ROUTER_DIRECTIVES, Routes } from '@angular/router'; import { ROUTER_DIRECTIVES } from '@angular/router';
import { CrisisDetailComponent } from './crisis-detail.component.1';
import { CrisisListComponent } from './crisis-list.component.1';
import { CrisisService } from './crisis.service'; import { CrisisService } from './crisis.service';
// #docregion minus-imports // #docregion minus-imports
@ -16,13 +14,5 @@ import { CrisisService } from './crisis.service';
providers: [CrisisService] providers: [CrisisService]
// #enddocregion providers // #enddocregion providers
}) })
// #docregion route-config
@Routes([
// #docregion default-route
{path: '/', component: CrisisListComponent}, // , useAsDefault: true}, // coming soon
// #enddocregion default-route
{path: '/:id', component: CrisisDetailComponent}
])
// #enddocregion route-config
export class CrisisCenterComponent { } export class CrisisCenterComponent { }
// #enddocregion minus-imports // #enddocregion minus-imports

View File

@ -1,9 +1,7 @@
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { ROUTER_DIRECTIVES, Routes } from '@angular/router'; import { ROUTER_DIRECTIVES } from '@angular/router';
import { CrisisDetailComponent } from './crisis-detail.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisService } from './crisis.service'; import { CrisisService } from './crisis.service';
@Component({ @Component({
@ -14,9 +12,5 @@ import { CrisisService } from './crisis.service';
directives: [ROUTER_DIRECTIVES], directives: [ROUTER_DIRECTIVES],
providers: [CrisisService] providers: [CrisisService]
}) })
@Routes([
{path: '', component: CrisisListComponent}, // , useAsDefault: true}, // coming soon
{path: '/:id', component: CrisisDetailComponent}
])
export class CrisisCenterComponent { } export class CrisisCenterComponent { }
// #enddocregion // #enddocregion

View File

@ -0,0 +1,18 @@
// #docregion
import { RouterConfig } from '@angular/router';
import { CrisisDetailComponent } from './crisis-detail.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component';
// #docregion routes
export const CrisisCenterRoutes: RouterConfig = [
{
path: '/crisis-center',
component: CrisisCenterComponent,
children: [
{ path: '/', component: CrisisListComponent },
{ path: '/:id', component: CrisisDetailComponent }
]
}
];
// #enddocregion routes

View File

@ -0,0 +1,22 @@
// #docregion
import { RouterConfig } from '@angular/router';
import { CrisisDetailComponent } from './crisis-detail.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component';
// #docregion routes
export const CrisisCenterRoutes: RouterConfig = [
{
path: '/crisis-center',
component: CrisisCenterComponent,
index: true,
children: [
{ path: '/:id', component: CrisisDetailComponent },
{ path: '/', component: CrisisListComponent,
index: true
}
]
}
];
// #enddocregion routes

View File

@ -0,0 +1,48 @@
// #docplaster
// #docregion
import { RouterConfig } from '@angular/router';
import { CrisisDetailComponent } from './crisis-detail.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component';
import { CrisisAdminComponent } from './crisis-admin.component';
import { CanDeactivateGuard } from '../interfaces';
export const CrisisCenterRoutes: RouterConfig = [
{
path: '/crisis-center',
component: CrisisCenterComponent,
index: true,
children: [
// #docregion admin-route-no-guard
{
path: '/admin',
component: CrisisAdminComponent
},
// #enddocregion admin-route-no-guard
{
path: '/:id',
component: CrisisDetailComponent,
canDeactivate: [CanDeactivateGuard]
},
{
path: '/',
component: CrisisListComponent,
index: true
}
]
}
];
// #enddocregion
/*
// #docregion auth-guard
import { AuthGuard } from '../auth.guard';
{
path: '/admin',
component: CrisisAdminComponent,
canActivate: [AuthGuard]
}
// #enddocregion auth-guard
*/

View File

@ -0,0 +1,50 @@
// #docplaster
// #docregion
import { RouterConfig } from '@angular/router';
import { CrisisDetailComponent } from './crisis-detail.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component';
import { CrisisAdminComponent } from './crisis-admin.component';
import { CanDeactivateGuard } from '../interfaces';
import { AuthGuard } from '../auth.guard';
export const CrisisCenterRoutes: RouterConfig = [
{
path: '/crisis-center',
component: CrisisCenterComponent,
index: true,
children: [
{
path: '/admin',
component: CrisisAdminComponent,
canActivate: [AuthGuard]
},
{
path: '/:id',
component: CrisisDetailComponent,
canDeactivate: [CanDeactivateGuard]
},
// #docregion default-route
{
path: '/',
component: CrisisListComponent,
index: true
}
// #enddocregion default-route
]
}
];
// #enddocregion
/*
// #docregion auth-guard
import { AuthGuard } from '../auth.guard';
{
path: '/admin',
component: CrisisAdminComponent,
canActivate: [AuthGuard]
}
// #enddocregion auth-guard
*/

View File

@ -0,0 +1,35 @@
// #docregion
import { RouterConfig } from '@angular/router';
import { CrisisDetailComponent } from './crisis-detail.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component';
import { CrisisAdminComponent } from './crisis-admin.component';
import { CanDeactivateGuard } from '../interfaces';
import { AuthGuard } from '../auth.guard';
export const CrisisCenterRoutes: RouterConfig = [
{
path: '/crisis-center',
component: CrisisCenterComponent,
index: true,
children: [
// #docregion admin-route
{
path: '/admin',
component: CrisisAdminComponent,
canActivate: [AuthGuard]
},
// #enddocregion admin-route
{
path: '/:id',
component: CrisisDetailComponent,
canDeactivate: [CanDeactivateGuard]
},
{ path: '/',
component: CrisisListComponent,
index: true
}
]
}
];

View File

@ -1,14 +1,15 @@
// #docplaster // #docplaster
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
import { OnActivate, Router, RouteSegment } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromPromise';
import { Crisis, CrisisService } from './crisis.service'; import { Crisis, CrisisService } from './crisis.service';
// #docregion routerCanDeactivate
// import { CanDeactivate } from '@angular/router';
import { DialogService } from '../dialog.service'; import { DialogService } from '../dialog.service';
// #enddocregion routerCanDeactivate
@Component({ @Component({
// #docregion template // #docregion template
template: ` template: `
@ -29,23 +30,31 @@ import { DialogService } from '../dialog.service';
// #enddocregion template // #enddocregion template
styles: ['input {width: 20em}'] styles: ['input {width: 20em}']
}) })
// #docregion routerCanDeactivate, cancel-save // #docregion cancel-save
export class CrisisDetailComponent implements OnActivate {// , CanDeactivate { export class CrisisDetailComponent implements OnInit, OnDestroy {
crisis: Crisis; crisis: Crisis;
editName: string; editName: string;
// #enddocregion ngOnDestroy
private sub: any;
// #enddocregion ngOnDestroy
// #enddocregion routerCanDeactivate, cancel-save // #enddocregion cancel-save
constructor( constructor(
private service: CrisisService, private service: CrisisService,
private router: Router, private router: Router,
private dialog: DialogService private route: ActivatedRoute,
private dialogService: DialogService
) { } ) { }
// #docregion ngOnActivate // #docregion ngOnInit
routerOnActivate(curr: RouteSegment): void { ngOnInit() {
let id = +curr.getParam('id'); this.sub = this.route
this.service.getCrisis(id).then(crisis => { .params
.subscribe(params => {
let id = +params['id'];
this.service.getCrisis(id)
.then(crisis => {
if (crisis) { if (crisis) {
this.editName = crisis.name; this.editName = crisis.name;
this.crisis = crisis; this.crisis = crisis;
@ -53,25 +62,20 @@ export class CrisisDetailComponent implements OnActivate {// , CanDeactivate {
this.gotoCrises(); this.gotoCrises();
} }
}); });
});
} }
// #enddocregion ngOnActivate // #enddocregion ngOnInit
// #docregion routerCanDeactivate // #enddocregion ngOnDestroy
// NOT IMPLEMENTED YET ngOnDestroy() {
routerCanDeactivate(): any { if (this.sub) {
// Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged. this.sub.unsubscribe();
if (!this.crisis || this.crisis.name === this.editName) {
return true;
} }
// Otherwise ask the user with the dialog service and return its
// promise which resolves to true or false when the user decides
return this.dialog.confirm('Discard changes?');
} }
// #enddocregion routerCanDeactivate // #enddocregion ngOnDestroy
// #docregion cancel-save // #docregion cancel-save
cancel() { cancel() {
this.editName = this.crisis.name;
this.gotoCrises(); this.gotoCrises();
} }
@ -81,13 +85,30 @@ export class CrisisDetailComponent implements OnActivate {// , CanDeactivate {
} }
// #enddocregion cancel-save // #enddocregion cancel-save
// #docregion cancel-save-only
canDeactivate(): Observable<boolean> | boolean {
// Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged
if (!this.crisis || this.crisis.name === this.editName) {
return true;
}
// Otherwise ask the user with the dialog service and return its
// promise which resolves to true or false when the user decides
let p = this.dialogService.confirm('Discard changes?');
let o = Observable.fromPromise(p);
return o;
}
// #enddocregion cancel-save-only
// #docregion gotoCrises // #docregion gotoCrises
gotoCrises() { gotoCrises() {
// Like <a [routerLink]="[/crisis-center/]">Crisis Center</a let crisisId = this.crisis ? this.crisis.id : null;
this.router.navigateByUrl('/crisis-center/'); // absolute url // Pass along the hero id if available
// so that the CrisisListComponent can select that hero.
// Add a totally useless `foo` parameter for kicks.
this.router.navigate(['/crisis-center', { id: crisisId, foo: 'foo' }], { relativeTo: this.route });
} }
// #enddocregion gotoCrises // #enddocregion gotoCrises
// #docregion routerCanDeactivate, cancel-save // #docregion cancel-save
} }
// #enddocregion routerCanDeactivate, cancel-save // #enddocregion cancel-save
// #enddocregion // #enddocregion

View File

@ -1,7 +1,9 @@
// #docplaster // #docplaster
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
import { CanDeactivate, OnActivate, Router, RouteSegment } from '@angular/router'; import { Router, ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromPromise';
import { Crisis, CrisisService } from './crisis.service'; import { Crisis, CrisisService } from './crisis.service';
import { DialogService } from '../dialog.service'; import { DialogService } from '../dialog.service';
@ -25,22 +27,25 @@ import { DialogService } from '../dialog.service';
styles: ['input {width: 20em}'] styles: ['input {width: 20em}']
}) })
export class CrisisDetailComponent implements OnActivate, CanDeactivate { export class CrisisDetailComponent implements OnInit, OnDestroy {
crisis: Crisis; crisis: Crisis;
editName: string; editName: string;
private curSegment: RouteSegment; private sub: any;
constructor( constructor(
private service: CrisisService, private service: CrisisService,
private route: ActivatedRoute,
private router: Router, private router: Router,
private dialog: DialogService private dialogService: DialogService
) { } ) { }
routerOnActivate(curr: RouteSegment) { ngOnInit() {
this.curSegment = curr; this.sub = this.route
.params
let id = +curr.getParam('id'); .subscribe(params => {
this.service.getCrisis(id).then(crisis => { let id = +params['id'];
this.service.getCrisis(id)
.then(crisis => {
if (crisis) { if (crisis) {
this.editName = crisis.name; this.editName = crisis.name;
this.crisis = crisis; this.crisis = crisis;
@ -48,20 +53,16 @@ export class CrisisDetailComponent implements OnActivate, CanDeactivate {
this.gotoCrises(); this.gotoCrises();
} }
}); });
});
} }
routerCanDeactivate(): any { ngOnDestroy() {
// Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged. if (this.sub) {
if (!this.crisis || this.crisis.name === this.editName) { this.sub.unsubscribe();
return true;
} }
// Otherwise ask the user with the dialog service and return its
// promise which resolves to true or false when the user decides
return this.dialog.confirm('Discard changes?');
} }
cancel() { cancel() {
this.editName = this.crisis.name;
this.gotoCrises(); this.gotoCrises();
} }
@ -70,6 +71,18 @@ export class CrisisDetailComponent implements OnActivate, CanDeactivate {
this.gotoCrises(); this.gotoCrises();
} }
canDeactivate(): Observable<boolean> | boolean {
// Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged
if (!this.crisis || this.crisis.name === this.editName) {
return true;
}
// Otherwise ask the user with the dialog service and return its
// promise which resolves to true or false when the user decides
let p = this.dialogService.confirm('Discard changes?');
let o = Observable.fromPromise(p);
return o;
}
// #docregion gotoCrises // #docregion gotoCrises
gotoCrises() { gotoCrises() {
let crisisId = this.crisis ? this.crisis.id : null; let crisisId = this.crisis ? this.crisis.id : null;
@ -79,9 +92,6 @@ export class CrisisDetailComponent implements OnActivate, CanDeactivate {
// #docregion gotoCrises-navigate // #docregion gotoCrises-navigate
// Absolute link // Absolute link
this.router.navigate(['/crisis-center', {id: crisisId, foo: 'foo'}]); this.router.navigate(['/crisis-center', {id: crisisId, foo: 'foo'}]);
// Relative link
// this.router.navigate(['../', {id: crisisId, foo: 'foo'}], this.curSegment);
// #enddocregion gotoCrises-navigate // #enddocregion gotoCrises-navigate
} }
// #enddocregion gotoCrises // #enddocregion gotoCrises

View File

@ -1,7 +1,7 @@
// #docplaster // #docplaster
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
import { OnActivate, Router, RouteSegment } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { Crisis, CrisisService } from './crisis.service'; import { Crisis, CrisisService } from './crisis.service';
@ -17,20 +17,34 @@ import { Crisis, CrisisService } from './crisis.service';
`, `,
// #enddocregion template // #enddocregion template
}) })
export class CrisisListComponent implements OnActivate { export class CrisisListComponent implements OnInit, OnDestroy {
crises: Crisis[]; crises: Crisis[];
selectedId: number;
private sub: any;
constructor( constructor(
private service: CrisisService, private service: CrisisService,
private route: ActivatedRoute,
private router: Router) {} private router: Router) {}
routerOnActivate(curr: RouteSegment): void { ngOnInit() {
this.service.getCrises().then(crises => this.crises = crises); this.sub = this.route
.params
.subscribe(params => {
this.selectedId = +params['id'];
this.service.getCrises()
.then(crises => this.crises = crises);
});
}
ngOnDestroy() {
this.sub.unsubscribe();
} }
// #docregion select // #docregion select
onSelect(crisis: Crisis) { onSelect(crisis: Crisis) {
this.router.navigateByUrl( `/crisis-list/${crisis.id}`); // Absolute link
this.router.navigate(['/crisis-center', crisis.id]);
} }
// #enddocregion select // #enddocregion select
} }

View File

@ -1,7 +1,7 @@
// #docplaster // #docplaster
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
import { OnActivate, Router, RouteSegment, RouteTree } from '@angular/router'; import { Router, ActivatedRoute } from '@angular/router';
import { Crisis, CrisisService } from './crisis.service'; import { Crisis, CrisisService } from './crisis.service';
@ -16,28 +16,36 @@ import { Crisis, CrisisService } from './crisis.service';
</ul> </ul>
`, `,
}) })
export class CrisisListComponent implements OnActivate { export class CrisisListComponent implements OnInit, OnDestroy {
crises: Crisis[]; crises: Crisis[];
private currSegment: RouteSegment;
private selectedId: number; private selectedId: number;
private sub: any;
constructor( constructor(
private service: CrisisService, private service: CrisisService,
private route: ActivatedRoute,
private router: Router) { } private router: Router) { }
isSelected(crisis: Crisis) { return crisis.id === this.selectedId; } isSelected(crisis: Crisis) { return crisis.id === this.selectedId; }
routerOnActivate(curr: RouteSegment, prev: RouteSegment, currTree: RouteTree) { ngOnInit() {
this.currSegment = curr; this.sub = this.route
this.selectedId = +currTree.parent(curr).getParam('id'); .params
this.service.getCrises().then(crises => this.crises = crises); .subscribe(params => {
this.selectedId = +params['id'];
this.service.getCrises()
.then(crises => this.crises = crises);
});
}
ngOnDestroy() {
if (this.sub) {
this.sub.unsubscribe();
}
} }
onSelect(crisis: Crisis) { onSelect(crisis: Crisis) {
// Absolute link // Navigate with Absolute link
// this.router.navigate([`/crisis-center`, crisis.id]); this.router.navigate(['/crisis-center', crisis.id]);
// Relative link
this.router.navigate([`./${crisis.id}`], this.currSegment);
} }
} }

View File

@ -1,5 +1,5 @@
// #docplaster // #docplaster
// #docregion
export class Crisis { export class Crisis {
constructor(public id: number, public name: string) { } constructor(public id: number, public name: string) { }
} }
@ -14,7 +14,7 @@ const CRISES = [
let crisesPromise = Promise.resolve(CRISES); let crisesPromise = Promise.resolve(CRISES);
// #docregion // #docregion
import { Injectable } from '@angular/core'; import {Injectable} from '@angular/core';
@Injectable() @Injectable()
export class CrisisService { export class CrisisService {

View File

@ -12,7 +12,8 @@ export class DialogService {
* Returns promise resolving to `true`=confirm or `false`=cancel * Returns promise resolving to `true`=confirm or `false`=cancel
*/ */
confirm(message?: string) { confirm(message?: string) {
return new Promise<boolean>((resolve, reject) => return new Promise<boolean>(resolve => {
resolve(window.confirm(message || 'Is it OK?'))); return resolve(window.confirm(message || 'Is it OK?'));
});
}; };
} }

View File

@ -1,6 +1,7 @@
// #docplaster
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
import { OnActivate, Router, RouteSegment } from '@angular/router'; import { Router, ActivatedRoute } from '@angular/router';
import { Hero, HeroService } from './hero.service'; import { Hero, HeroService } from './hero.service';
@ -21,26 +22,35 @@ import { Hero, HeroService } from './hero.service';
</div> </div>
`, `,
}) })
export class HeroDetailComponent implements OnActivate { export class HeroDetailComponent implements OnInit, OnDestroy {
hero: Hero; hero: Hero;
// #docregion ngOnInit
private sub: any;
// #enddocregion ngOnInit
// #docregion ctor // #docregion ctor
constructor( constructor(
private route: ActivatedRoute,
private router: Router, private router: Router,
private service: HeroService) {} private service: HeroService) {}
// #enddocregion ctor // #enddocregion ctor
// #docregion OnActivate // #docregion ngOnInit
routerOnActivate(curr: RouteSegment): void { ngOnInit() {
let id = +curr.getParam('id'); this.sub = this.route.params.subscribe(params => {
let id = +params['id']; // (+) converts string 'id' to a number
this.service.getHero(id).then(hero => this.hero = hero); this.service.getHero(id).then(hero => this.hero = hero);
});
} }
// #enddocregion OnActivate // #enddocregion ngOnInit
// #docregion ngOnDestroy
ngOnDestroy() {
this.sub.unsubscribe();
}
// #enddocregion ngOnDestroy
// #docregion gotoHeroes // #docregion gotoHeroes
gotoHeroes() { gotoHeroes() { this.router.navigate(['/heroes']); }
// Like <a [routerLink]="['/heroes']">Heroes</a>
this.router.navigate(['/heroes']);
}
// #enddocregion gotoHeroes // #enddocregion gotoHeroes
} }

View File

@ -0,0 +1,42 @@
// Snapshot version
// #docregion
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Hero, HeroService } from './hero.service';
@Component({
template: `
<h2>HEROES</h2>
<div *ngIf="hero">
<h3>"{{hero.name}}"</h3>
<div>
<label>Id: </label>{{hero.id}}</div>
<div>
<label>Name: </label>
<input [(ngModel)]="hero.name" placeholder="name"/>
</div>
<p>
<button (click)="gotoHeroes()">Back</button>
</p>
</div>
`,
})
export class HeroDetailComponent implements OnInit {
hero: Hero;
constructor(
private route: ActivatedRoute,
private router: Router,
private service: HeroService) {}
// #docregion snapshot
ngOnInit() {
// (+) converts string 'id' to a number
let id = +this.route.snapshot.params['id'];
this.service.getHero(id).then(hero => this.hero = hero);
}
// #enddocregion snapshot
gotoHeroes() { this.router.navigate(['/heroes']); }
}

View File

@ -1,6 +1,7 @@
// #docplaster
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
import { OnActivate, Router, RouteSegment } from '@angular/router'; import { Router, ActivatedRoute } from '@angular/router';
import { Hero, HeroService } from './hero.service'; import { Hero, HeroService } from './hero.service';
@ -21,30 +22,41 @@ import { Hero, HeroService } from './hero.service';
</div> </div>
`, `,
}) })
export class HeroDetailComponent implements OnActivate { export class HeroDetailComponent implements OnInit, OnDestroy {
hero: Hero; hero: Hero;
// #docregion ngOnInit
private sub: any;
// #enddocregion ngOnInit
// #docregion ctor // #docregion ctor
constructor( constructor(
private route: ActivatedRoute,
private router: Router, private router: Router,
private service: HeroService) {} private service: HeroService) {}
// #enddocregion ctor // #enddocregion ctor
// #docregion ngOnInit
// #docregion OnActivate ngOnInit() {
routerOnActivate(curr: RouteSegment): void { this.sub = this.route.params.subscribe(params => {
let id = +curr.getParam('id'); let id = +params['id']; // (+) converts string 'id' to a number
this.service.getHero(id).then(hero => this.hero = hero); this.service.getHero(id).then(hero => this.hero = hero);
});
} }
// #enddocregion OnActivate // #enddocregion ngOnInit
// #docregion ngOnDestroy
ngOnDestroy() {
this.sub.unsubscribe();
}
// #enddocregion ngOnDestroy
// #docregion gotoHeroes-navigate
gotoHeroes() { gotoHeroes() {
let heroId = this.hero ? this.hero.id : null; let heroId = this.hero ? this.hero.id : null;
// Pass along the hero id if available // Pass along the hero id if available
// so that the HeroList component can select that hero. // so that the HeroList component can select that hero.
// Add a totally useless `foo` parameter for kicks. this.router.navigate(['/heroes'], { queryParams: { id: `${heroId}`, foo: 'foo' } });
// #docregion gotoHeroes-navigate
this.router.navigate([`/heroes`, {id: heroId, foo: 'foo'}]);
// #enddocregion gotoHeroes-navigate
} }
// #enddocregion gotoHeroes-navigate
} }

View File

@ -43,7 +43,7 @@ export class HeroListComponent implements OnInit {
// #enddocregion // #enddocregion
/* A link parameters array /* A link parameters array
// #docregion link-parameters-array // #docregion link-parameters-array
['HeroDetail', { id: hero.id }] // {id: 15} ['/hero', hero.id] // { 15 }
// #enddocregion link-parameters-array // #enddocregion link-parameters-array
*/ */

View File

@ -0,0 +1,64 @@
// #docplaster
// #docregion
// TODO SOMEDAY: Feature Componetized like CrisisCenter
import { Component, OnInit, OnDestroy } from '@angular/core';
// #docregion import-router
import { Router } from '@angular/router';
// #enddocregion import-router
import { Hero, HeroService } from './hero.service';
@Component({
// #docregion template
template: `
<h2>HEROES</h2>
<ul class="items">
<li *ngFor="let hero of heroes"
[class.selected]="isSelected(hero)"
(click)="onSelect(hero)">
<span class="badge">{{hero.id}}</span> {{hero.name}}
</li>
</ul>
`
// #enddocregion template
})
export class HeroListComponent implements OnInit, OnDestroy {
heroes: Hero[];
// #docregion ctor
private selectedId: number;
private sub: any;
constructor(
private service: HeroService,
private router: Router) {}
// #enddocregion ctor
ngOnInit() {
this.sub = this.router
.routerState
.queryParams
.subscribe(params => {
this.selectedId = +params['id'];
this.service.getHeroes()
.then(heroes => this.heroes = heroes);
});
}
ngOnDestroy() {
this.sub.unsubscribe();
}
// #enddocregion ctor
// #docregion isSelected
isSelected(hero: Hero) { return hero.id === this.selectedId; }
// #enddocregion isSelected
// #docregion select
onSelect(hero: Hero) {
this.router.navigate(['/hero', hero.id]);
}
// #enddocregion select
}
// #enddocregion

View File

@ -1,9 +1,9 @@
// #docplaster // #docplaster
// #docregion // #docregion
// TODO SOMEDAY: Feature Componetized like CrisisCenter // TODO SOMEDAY: Feature Componetized like CrisisCenter
import { Component } from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
// #docregion import-router // #docregion import-router
import { OnActivate, Router, RouteSegment, RouteTree } from '@angular/router'; import { Router } from '@angular/router';
// #enddocregion import-router // #enddocregion import-router
import { Hero, HeroService } from './hero.service'; import { Hero, HeroService } from './hero.service';
@ -22,22 +22,34 @@ import { Hero, HeroService } from './hero.service';
` `
// #enddocregion template // #enddocregion template
}) })
export class HeroListComponent implements OnActivate { export class HeroListComponent implements OnInit, OnDestroy {
heroes: Hero[]; heroes: Hero[];
// #docregion ctor // #docregion ctor
private selectedId: number; private selectedId: number;
private sub: any;
constructor( constructor(
private service: HeroService, private service: HeroService,
private router: Router) { } private router: Router) {}
// #enddocregion ctor // #enddocregion ctor
routerOnActivate(curr: RouteSegment, prev?: RouteSegment, currTree?: RouteTree, prevTree?: RouteTree): void { ngOnInit() {
this.selectedId = +curr.getParam('id'); this.sub = this.router
this.service.getHeroes().then(heroes => this.heroes = heroes); .routerState
.queryParams
.subscribe(params => {
this.selectedId = +params['id'];
this.service.getHeroes()
.then(heroes => this.heroes = heroes);
});
} }
ngOnDestroy() {
this.sub.unsubscribe();
}
// #enddocregion ctor
// #docregion isSelected // #docregion isSelected
isSelected(hero: Hero) { return hero.id === this.selectedId; } isSelected(hero: Hero) { return hero.id === this.selectedId; }
// #enddocregion isSelected // #enddocregion isSelected

View File

@ -0,0 +1,12 @@
// #docregion
import { RouterConfig } from '@angular/router';
import { HeroListComponent } from './hero-list.component';
import { HeroDetailComponent } from './hero-detail.component';
export const HeroesRoutes: RouterConfig = [
{ path: '/heroes', component: HeroListComponent },
// #docregion hero-detail-route
{ path: '/hero/:id', component: HeroDetailComponent }
// #enddocregion hero-detail-route
];
// #enddocregion

View File

@ -0,0 +1,13 @@
// #docregion
import { CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs/Observable';
export interface CanComponentDeactivate {
canDeactivate: () => boolean | Observable<boolean>;
}
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
canDeactivate(component: CanComponentDeactivate): Observable<boolean> | boolean {
return component.canDeactivate ? component.canDeactivate() : true;
}
}

View File

@ -0,0 +1,44 @@
// #docregion
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from './auth.service';
@Component({
selector: 'login',
template: `
<h2>LOGIN</h2>
<p>{{message}}</p>
<p>
<button (click)="login()" *ngIf="!authService.isLoggedIn">Login</button>
<button (click)="logout()" *ngIf="authService.isLoggedIn">Logout</button>
</p>`
})
export class LoginComponent {
message: string;
constructor(public authService: AuthService, public router: Router) {
this.setMessage();
}
setMessage() {
this.message = 'Logged ' + (this.authService.isLoggedIn ? 'in' : 'out');
}
login() {
this.message = "Trying to log in ...";
this.authService.login().subscribe(() => {
this.setMessage();
if (this.authService.isLoggedIn) {
// Todo: capture where the user was going and nav there.
// Meanwhile redirect the user to the crisis admin
this.router.navigate(['/crisis-center/admin']);
}
});
}
logout() {
this.authService.logout();
this.setMessage();
}
}

View File

@ -0,0 +1,10 @@
// #docregion
import { AuthGuard } from './auth.guard';
import { AuthService } from './auth.service';
import { LoginComponent } from './login.component';
export const LoginRoutes = [
{ path: '/login', component: LoginComponent }
];
export const AUTH_PROVIDERS = [AuthGuard, AuthService];

View File

@ -1,23 +1,25 @@
/* First version */ /* First version */
// #docplaster // #docplaster
// #docregion all // #docregion all
// main entry point
import { bootstrap } from '@angular/platform-browser-dynamic'; import { bootstrap } from '@angular/platform-browser-dynamic';
import { ROUTER_PROVIDERS } from '@angular/router';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
// #enddocregion all import { APP_ROUTER_PROVIDERS } from './app.routes';
// #enddocregion
/* Can't use AppComponent ... but display as if we can /* Can't use AppComponent ... but display as if we can
// #docregion all // #docregion all
bootstrap(AppComponent, [ bootstrap(AppComponent, [
// #enddocregion all // #enddocregion all
*/ */
// Actually use the v.1 component // Actually use the v.1 component
import { AppComponent as ac } from './app.component.1'; import { AppComponent as ac } from './app.component.ts'; // './app.component.1';
bootstrap(ac, [ bootstrap(ac, [
// #docregion all // #docregion all
ROUTER_PROVIDERS APP_ROUTER_PROVIDERS
]); ])
.catch(err => console.error(err));
// #enddocregion all // #enddocregion all

View File

@ -2,30 +2,32 @@
// For Milestone #2 // For Milestone #2
// Also includes digression on HashPathStrategy (not used in the final app) // Also includes digression on HashPathStrategy (not used in the final app)
// #docplaster // #docplaster
// #docregion // #docregion
// main entry point
import { bootstrap } from '@angular/platform-browser-dynamic'; import { bootstrap } from '@angular/platform-browser-dynamic';
import { ROUTER_PROVIDERS } from '@angular/router';
// Add these symbols to override the `LocationStrategy` // Add these symbols to override the `LocationStrategy`
import { LocationStrategy, import { LocationStrategy,
HashLocationStrategy } from '@angular/common'; HashLocationStrategy } from '@angular/common';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { APP_ROUTER_PROVIDERS } from './app.routes';
// #enddocregion // #enddocregion
/* Can't use AppComponent ... but display as if we can /* Can't use AppComponent ... but display as if we can
// #docregion // #docregion
bootstrap(AppComponent, [ bootstrap(AppComponent, [
// #enddocregion // #enddocregion
*/ */
// Actually use the v.2 component // Actually use the v.2 component
import { AppComponent as ac } from './app.component.2'; import { AppComponent as ac } from './app.component.ts'; // './app.component.2';
bootstrap(ac, [ bootstrap(ac, [
// #docregion // #docregion
ROUTER_PROVIDERS, APP_ROUTER_PROVIDERS,
{ provide: LocationStrategy, useClass: HashLocationStrategy } // .../#/crisis-center/ { provide: LocationStrategy, useClass: HashLocationStrategy } // .../#/crisis-center/
]);
])
.catch(err => console.error(err));
// #enddocregion // #enddocregion

View File

@ -1,7 +1,11 @@
/* third version */
// #docregion // #docregion
// main entry point
import { bootstrap } from '@angular/platform-browser-dynamic'; import { bootstrap } from '@angular/platform-browser-dynamic';
import { ROUTER_PROVIDERS } from '@angular/router';
import { AppComponent } from './app.component.3'; import { AppComponent } from './app.component.3';
import { APP_ROUTER_PROVIDERS } from './app.routes';
bootstrap(AppComponent, [ROUTER_PROVIDERS]); bootstrap(AppComponent, [
APP_ROUTER_PROVIDERS
])
.catch(err => console.error(err));

View File

@ -1,7 +1,10 @@
// #docregion // #docregion
// main entry point
import { bootstrap } from '@angular/platform-browser-dynamic'; import { bootstrap } from '@angular/platform-browser-dynamic';
import { ROUTER_PROVIDERS } from '@angular/router';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { APP_ROUTER_PROVIDERS } from './app.routes';
bootstrap(AppComponent, [ROUTER_PROVIDERS]); bootstrap(AppComponent, [
APP_ROUTER_PROVIDERS
])
.catch(err => console.error(err));

View File

@ -3,7 +3,7 @@
<html> <html>
<head> <head>
<!-- #docregion base-href --> <!-- #docregion base-href -->
<base href="/"> <base href=".">
<!-- #enddocregion base-href --> <!-- #enddocregion base-href -->
<title>Router Sample v.1</title> <title>Router Sample v.1</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
@ -20,7 +20,7 @@
<script src="systemjs.config.js"></script> <script src="systemjs.config.js"></script>
<script> <script>
System.import('app/main.1') // <----- ONLY CHANGE System.import('app/main.1') // <----- ONLY CHANGE
.then(null, console.error.bind(console)); .catch(function(err){ console.error(err); });
</script> </script>
</head> </head>

View File

@ -2,7 +2,7 @@
<!-- #docregion --> <!-- #docregion -->
<html> <html>
<head> <head>
<base href="/"> <base href=".">
<title>Router Sample v.2</title> <title>Router Sample v.2</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
@ -18,7 +18,7 @@
<script src="systemjs.config.js"></script> <script src="systemjs.config.js"></script>
<script> <script>
System.import('app/main.2') // <----- ONLY CHANGE System.import('app/main.2') // <----- ONLY CHANGE
.then(null, console.error.bind(console)); .catch(function(err){ console.error(err); });
</script> </script>
</head> </head>

View File

@ -2,7 +2,7 @@
<!-- #docregion --> <!-- #docregion -->
<html> <html>
<head> <head>
<base href="/"> <base href=".">
<title>Router Sample v.3</title> <title>Router Sample v.3</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
@ -18,7 +18,7 @@
<script src="systemjs.config.js"></script> <script src="systemjs.config.js"></script>
<script> <script>
System.import('app/main.3') // <----- ONLY CHANGE System.import('app/main.3') // <----- ONLY CHANGE
.then(null, console.error.bind(console)); .catch(function(err){ console.error(err); });
</script> </script>
</head> </head>

View File

@ -4,7 +4,7 @@
<html> <html>
<head> <head>
<!-- Set the base href --> <!-- Set the base href -->
<base href="/"> <base href=".">
<title>Router Sample</title> <title>Router Sample</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
@ -19,7 +19,8 @@
<script src="systemjs.config.js"></script> <script src="systemjs.config.js"></script>
<script> <script>
System.import('app').catch(function(err){ console.error(err); }); System.import('app')
.catch(function(err){ console.error(err); });
</script> </script>
</head> </head>

View File

@ -3,7 +3,7 @@
"files":[ "files":[
"!**/*.d.ts", "!**/*.d.ts",
"!**/*.js", "!**/*.js",
"!**/*.[1,2,3].*", "!**/*.[1,2,3,4,5].*",
"!app/crisis-list.component.ts", "!app/crisis-list.component.ts",
"!app/hero-list.component.ts", "!app/hero-list.component.ts",
"!app/crisis-center/add-crisis.component.ts" "!app/crisis-center/add-crisis.component.ts"

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Server Communication', function () { describe('Server Communication', function () {
beforeAll(function () { beforeAll(function () {

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Structural Directives', function () { describe('Structural Directives', function () {
// tests interact - so we need beforeEach instead of beforeAll // tests interact - so we need beforeEach instead of beforeAll

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Style Guide', function () { describe('Style Guide', function () {
it('01-01', function () { it('01-01', function () {
browser.get('#/01-01'); browser.get('#/01-01');

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Documentation StyleGuide E2E Tests', function() { describe('Documentation StyleGuide E2E Tests', function() {
let expectedMsg = 'My First Angular 2 App'; let expectedMsg = 'My First Angular 2 App';

View File

@ -48,6 +48,9 @@
// Add package entries for angular packages // Add package entries for angular packages
ngPackageNames.forEach(setPackageConfig); ngPackageNames.forEach(setPackageConfig);
// No umd for router yet
packages['@angular/router'] = { main: 'index.js', defaultExtension: 'js' };
var config = { var config = {
map: map, map: map,
packages: packages packages: packages

View File

@ -6,16 +6,18 @@
(function(global) { (function(global) {
var ngVer = '@2.0.0-rc.2'; // lock in the angular package version; do not let it float to current! var ngVer = '@2.0.0-rc.2'; // lock in the angular package version; do not let it float to current!
var routerVer = '@3.0.0-alpha.3'; // lock router version
//map tells the System loader where to look for things //map tells the System loader where to look for things
var map = { var map = {
'app': 'app', 'app': 'app',
'@angular': 'https://npmcdn.com/@angular', // sufficient if we didn't pin the version '@angular': 'https://npmcdn.com/@angular', // sufficient if we didn't pin the version
'@angular/router': 'https://npmcdn.com/@angular/router' + routerVer,
'angular2-in-memory-web-api': 'https://npmcdn.com/angular2-in-memory-web-api', // get latest 'angular2-in-memory-web-api': 'https://npmcdn.com/angular2-in-memory-web-api', // get latest
'rxjs': 'https://npmcdn.com/rxjs@5.0.0-beta.6', 'rxjs': 'https://npmcdn.com/rxjs@5.0.0-beta.6',
'ts': 'https://npmcdn.com/plugin-typescript@4.0.10/lib/plugin.js', 'ts': 'https://npmcdn.com/plugin-typescript@4.0.10/lib/plugin.js',
'typescript': 'https://npmcdn.com/typescript@1.8.10/lib/typescript.js', 'typescript': 'https://npmcdn.com/typescript@1.9.0-dev.20160409/lib/typescript.js',
}; };
//packages tells the System loader how to load when no filename and/or no extension //packages tells the System loader how to load when no filename and/or no extension
@ -32,7 +34,6 @@
'http', 'http',
'platform-browser', 'platform-browser',
'platform-browser-dynamic', 'platform-browser-dynamic',
'router',
'router-deprecated', 'router-deprecated',
'upgrade', 'upgrade',
]; ];
@ -53,6 +54,9 @@
//packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' }; //packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' };
}); });
// No umd for router yet
packages['@angular/router'] = { main: 'index.js', defaultExtension: 'js' };
var config = { var config = {
// DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER // DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER
transpiler: 'ts', transpiler: 'ts',

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
// Not yet complete // Not yet complete
describe('Template Syntax', function () { describe('Template Syntax', function () {

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Tutorial part 1', () => { describe('Tutorial part 1', () => {
let expectedH1 = 'Tour of Heroes'; let expectedH1 = 'Tour of Heroes';

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Tutorial', function () { describe('Tutorial', function () {
beforeAll(function () { beforeAll(function () {

View File

@ -1,4 +1,5 @@
/// <reference path='../_protractor/e2e.d.ts' /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('TOH Http Chapter', function () { describe('TOH Http Chapter', function () {
beforeEach(function () { beforeEach(function () {

View File

@ -2,6 +2,6 @@
"globalDependencies": { "globalDependencies": {
"core-js": "registry:dt/core-js#0.0.0+20160317120654", "core-js": "registry:dt/core-js#0.0.0+20160317120654",
"jasmine": "registry:dt/jasmine#2.2.0+20160505161446", "jasmine": "registry:dt/jasmine#2.2.0+20160505161446",
"node": "registry:dt/node#4.0.0+20160509154515" "node": "registry:dt/node#6.0.0+20160613154055"
} }
} }

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Upgrade Tests', function () { describe('Upgrade Tests', function () {
// Protractor doesn't support the UpgradeAdapter's asynchronous // Protractor doesn't support the UpgradeAdapter's asynchronous

View File

@ -1,4 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict'; 'use strict';
// Angular E2E Testing Guide: // Angular E2E Testing Guide:

View File

@ -1,4 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict'; 'use strict';
// Angular E2E Testing Guide: // Angular E2E Testing Guide:

View File

@ -1,4 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict'; 'use strict';
// Angular E2E Testing Guide: // Angular E2E Testing Guide:

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('User Input Tests', function () { describe('User Input Tests', function () {
beforeAll(function () { beforeAll(function () {

View File

@ -1,4 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" /> /// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('QuickStart E2E Tests', function () { describe('QuickStart E2E Tests', function () {
let expectedMsg = 'Hello from Angular 2 App with Webpack'; let expectedMsg = 'Hello from Angular 2 App with Webpack';

View File

@ -2,6 +2,6 @@
"globalDependencies": { "globalDependencies": {
"core-js": "registry:dt/core-js#0.0.0+20160317120654", "core-js": "registry:dt/core-js#0.0.0+20160317120654",
"jasmine": "registry:dt/jasmine#2.2.0+20160505161446", "jasmine": "registry:dt/jasmine#2.2.0+20160505161446",
"node": "registry:dt/node#4.0.0+20160509154515" "node": "registry:dt/node#6.0.0+20160613154055"
} }
} }

View File

@ -0,0 +1,10 @@
#sg-images.showcase.shadow-1
header.showcase-header
h2 Images
p.
To maintain visual consistency across documentation chapters, please follow the best
practices for authors outlined in the <a href="/docs/ImageGuide.pdf" target="_blank">Image
Guide</a>.
p.
The browser background template used for outlining screenshots is <a
href="/resources/images/backgrounds/browser-background-template.png" target="_blank">here</a>.

View File

@ -6,5 +6,6 @@
!= partial("_callouts") != partial("_callouts")
!= partial("_tables") != partial("_tables")
!= partial("_aside") != partial("_aside")
!= partial("_images")
//!= partial("_jump-nav") //!= partial("_jump-nav")

View File

@ -33,3 +33,6 @@ class="docs-landing")
footer footer
a(href="/docs/#{current.path[1]}/#{current.path[2]}/api/" class="button md-button") View API a(href="/docs/#{current.path[1]}/#{current.path[2]}/api/" class="button md-button") View API
.alert.is-helpful.
Not using Angular 2 yet? Perhaps you need the
<a href="https://www.dartdocs.org/documentation/angular/latest" target="_blank">API docs for the original AngularDart</a>.

Some files were not shown because too many files have changed in this diff Show More