Merge remote-tracking branch 'origin/master'

# Conflicts:
#	public/docs/_examples/cb-component-communication/e2e-spec.ts
#	public/docs/_examples/cb-component-communication/ts/app/app.component.ts
#	public/docs/_examples/dependency-injection/ts/app/main.1.ts
#	public/docs/ts/latest/tutorial/toh-pt1.jade
#	public/docs/ts/latest/tutorial/toh-pt2.jade
#	public/docs/ts/latest/tutorial/toh-pt3.jade
#	public/docs/ts/latest/tutorial/toh-pt4.jade
#	public/docs/ts/latest/tutorial/toh-pt5.jade
This commit is contained in:
Zhicheng Wang 2016-06-08 09:58:16 +08:00
commit f2dbdb3163
255 changed files with 794 additions and 767 deletions

View File

@ -636,7 +636,15 @@ gulp.task('_zip-examples', function() {
// Linting // Linting
gulp.task('lint', function() { gulp.task('lint', function() {
return gulp.src(['./public/docs/_examples/style-guide/ts/**/*.ts', '!./public/docs/_examples/style-guide/ts/**/*.avoid.ts']) return gulp.src([
'./public/docs/_examples/**/*.ts',
'!./public/docs/_examples/**/ts-snippets/*.ts',
'!./public/docs/_examples/style-guide/ts/**/*.avoid.ts',
'!./public/docs/_examples/**/node_modules/**/*',
'!./public/docs/_examples/_protractor/**/*',
'!./public/docs/_examples/**/typings/**/*',
'!./public/docs/_examples/**/typings-ng1/**/*'
])
.pipe(tslint({ .pipe(tslint({
rulesDirectory: ['node_modules/codelyzer'], rulesDirectory: ['node_modules/codelyzer'],
configuration: require('./tslint.json') configuration: require('./tslint.json')

View File

@ -31,7 +31,7 @@
"browser-sync": "^2.9.3", "browser-sync": "^2.9.3",
"canonical-path": "0.0.2", "canonical-path": "0.0.2",
"cross-spawn": "^4.0.0", "cross-spawn": "^4.0.0",
"codelyzer": "0.0.20", "codelyzer": "0.0.22",
"del": "^2.2.0", "del": "^2.2.0",
"dgeni": "^0.4.0", "dgeni": "^0.4.0",
"dgeni-packages": "^0.13.0", "dgeni-packages": "^0.13.0",

View File

@ -9,7 +9,7 @@ export class SalesTaxService {
constructor(private rateService: TaxRateService) { } constructor(private rateService: TaxRateService) { }
getVAT(value: string | number) { getVAT(value: string | number) {
let amount: number; let amount: number;
if (typeof value === "string"){ if (typeof value === 'string') {
amount = parseFloat(value); amount = parseFloat(value);
} else { } else {
amount = value; amount = value;

View File

@ -19,7 +19,7 @@ export class HighlightDirective {
// #enddocregion ctor // #enddocregion ctor
// #docregion mouse-methods // #docregion mouse-methods
onMouseEnter() { this.highlight("yellow"); } onMouseEnter() { this.highlight('yellow'); }
onMouseLeave() { this.highlight(null); } onMouseLeave() { this.highlight(null); }
private highlight(color: string) { private highlight(color: string) {

View File

@ -85,7 +85,7 @@ describe('Angular 1 to 2 Quick Reference Tests', function () {
posterButton.click().then(function () { posterButton.click().then(function () {
testImagesAreDisplayed(isDisplayed); testImagesAreDisplayed(isDisplayed);
}) });
} }
function getMovieRows() { function getMovieRows() {
@ -107,7 +107,7 @@ describe('Angular 1 to 2 Quick Reference Tests', function () {
} else { } else {
expect(favoriteHeroLabel.isDisplayed()).toBe(false); expect(favoriteHeroLabel.isDisplayed()).toBe(false);
} }
}) });
}) });
} }
}); });

View File

@ -19,8 +19,8 @@ describe('Component Communication Cookbook Tests', function () {
for (let i = 0; i < _heroNames.length; i++) { for (let i = 0; i < _heroNames.length; i++) {
let childTitle = heroes.get(i).element(by.tagName('h3')).getText(); let childTitle = heroes.get(i).element(by.tagName('h3')).getText();
let childDetail = heroes.get(i).element(by.tagName('p')).getText(); let childDetail = heroes.get(i).element(by.tagName('p')).getText();
expect(childTitle).toEqual(_heroNames[i] + ' says:') expect(childTitle).toEqual(_heroNames[i] + ' says:');
expect(childDetail).toContain(_masterName) expect(childDetail).toContain(_masterName);
} }
}); });
// ... // ...
@ -37,7 +37,7 @@ describe('Component Communication Cookbook Tests', function () {
let hero = parent.all(by.tagName('name-child')).get(_nonEmptyNameIndex); let hero = parent.all(by.tagName('name-child')).get(_nonEmptyNameIndex);
let displayName = hero.element(by.tagName('h3')).getText(); let displayName = hero.element(by.tagName('h3')).getText();
expect(displayName).toEqual(_nonEmptyName) expect(displayName).toEqual(_nonEmptyName);
}); });
it('should replace empty name with default name', function () { it('should replace empty name with default name', function () {
@ -47,7 +47,7 @@ describe('Component Communication Cookbook Tests', function () {
let hero = parent.all(by.tagName('name-child')).get(_emptyNameIndex); let hero = parent.all(by.tagName('name-child')).get(_emptyNameIndex);
let displayName = hero.element(by.tagName('h3')).getText(); let displayName = hero.element(by.tagName('h3')).getText();
expect(displayName).toEqual(_defaultName) expect(displayName).toEqual(_defaultName);
}); });
// ... // ...
// #enddocregion parent-to-child-setter // #enddocregion parent-to-child-setter
@ -82,7 +82,7 @@ describe('Component Communication Cookbook Tests', function () {
expect(actual.label).toBe(labelAfter2Minor); expect(actual.label).toBe(labelAfter2Minor);
expect(actual.count).toBe(3); expect(actual.count).toBe(3);
expect(actual.logs.get(2).getText()).toBe(logAfter2Minor); expect(actual.logs.get(2).getText()).toBe(logAfter2Minor);
}) });
}); });
}); });
@ -151,12 +151,14 @@ describe('Component Communication Cookbook Tests', function () {
// #enddocregion child-to-parent // #enddocregion child-to-parent
}); });
describe('Parent calls child via local var', function() { // Can't run timer tests in protractor because
countDownTimerTests('countdown-parent-lv') // interaction w/ zones causes all tests to freeze & timeout.
xdescribe('Parent calls child via local var', function() {
countDownTimerTests('countdown-parent-lv');
}); });
describe('Parent calls ViewChild', function() { xdescribe('Parent calls ViewChild', function() {
countDownTimerTests('countdown-parent-vc') countDownTimerTests('countdown-parent-vc');
}); });
function countDownTimerTests(parentTag: string) { function countDownTimerTests(parentTag: string) {

View File

@ -16,9 +16,20 @@ import { MissionControlComponent } from './missioncontrol.component';
NameParentComponent, NameParentComponent,
VersionParentComponent, VersionParentComponent,
VoteTakerComponent, VoteTakerComponent,
CountdownLocalVarParentComponent, MissionControlComponent,
CountdownViewChildParentComponent, ];
MissionControlComponent
] // Include Countdown examples
// unless in e2e tests which they break.
if (!/e2e/.test(location.search)) {
console.log('adding countdown timer examples');
directives.push(CountdownLocalVarParentComponent);
directives.push(CountdownViewChildParentComponent);
}
@Component({
selector: 'app',
templateUrl: 'app/app.component.html',
directives: directives
}) })
export class AppComponent { } export class AppComponent { }

View File

@ -19,7 +19,7 @@ import { Subscription } from 'rxjs/Subscription';
}) })
export class AstronautComponent implements OnDestroy { export class AstronautComponent implements OnDestroy {
@Input() astronaut: string; @Input() astronaut: string;
mission = "<no mission announced>"; mission = '<no mission announced>';
confirmed = false; confirmed = false;
announced = false; announced = false;
subscription: Subscription; subscription: Subscription;
@ -30,7 +30,7 @@ export class AstronautComponent implements OnDestroy{
this.mission = mission; this.mission = mission;
this.announced = true; this.announced = true;
this.confirmed = false; this.confirmed = false;
}) });
} }
confirm() { confirm() {

View File

@ -50,7 +50,7 @@ export class CountdownViewChildParentComponent implements AfterViewInit {
// Redefine `seconds()` to get from the `CountdownTimerComponent.seconds` ... // Redefine `seconds()` to get from the `CountdownTimerComponent.seconds` ...
// but wait a tick first to avoid one-time devMode // but wait a tick first to avoid one-time devMode
// unidirectional-data-flow-violation error // unidirectional-data-flow-violation error
setTimeout(() => this.seconds = () => this.timerComponent.seconds, 0) setTimeout(() => this.seconds = () => this.timerComponent.seconds, 0);
} }
start() { this.timerComponent.start(); } start() { this.timerComponent.start(); }

View File

@ -1,5 +1,5 @@
// #docregion // #docregion
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject'; import { Subject } from 'rxjs/Subject';
@Injectable() @Injectable()
@ -15,7 +15,7 @@ export class MissionService {
// Service message commands // Service message commands
announceMission(mission: string) { announceMission(mission: string) {
this.missionAnnouncedSource.next(mission) this.missionAnnouncedSource.next(mission);
} }
confirmMission(astronaut: string) { confirmMission(astronaut: string) {

View File

@ -21,7 +21,7 @@ import { MissionService } from './mission.service';
providers: [MissionService] providers: [MissionService]
}) })
export class MissionControlComponent { export class MissionControlComponent {
astronauts = ['Lovell', 'Swigert', 'Haise'] astronauts = ['Lovell', 'Swigert', 'Haise'];
history: string[] = []; history: string[] = [];
missions = ['Fly to the moon!', missions = ['Fly to the moon!',
'Fly to mars!', 'Fly to mars!',
@ -32,7 +32,7 @@ export class MissionControlComponent {
missionService.missionConfirmed$.subscribe( missionService.missionConfirmed$.subscribe(
astronaut => { astronaut => {
this.history.push(`${astronaut} confirmed the mission`); this.history.push(`${astronaut} confirmed the mission`);
}) });
} }
announce() { announce() {

View File

@ -18,7 +18,7 @@ import { VoterComponent } from './voter.component';
export class VoteTakerComponent { export class VoteTakerComponent {
agreed = 0; agreed = 0;
disagreed = 0; disagreed = 0;
voters = ['Mr. IQ', 'Ms. Universe', 'Bombasto'] voters = ['Mr. IQ', 'Ms. Universe', 'Bombasto'];
onVoted(agreed: boolean) { onVoted(agreed: boolean) {
agreed ? this.agreed++ : this.disagreed++; agreed ? this.agreed++ : this.disagreed++;

View File

@ -12,7 +12,7 @@ describe('Cookbook: component-relative paths', function () {
title: element( by.tagName( 'h1' )), title: element( by.tagName( 'h1' )),
absComp: element( by.css( 'absolute-path div' ) ), absComp: element( by.css( 'absolute-path div' ) ),
relComp: element( by.css( 'relative-path div' ) ) relComp: element( by.css( 'relative-path div' ) )
} };
} }
let page: Page; let page: Page;

View File

@ -66,7 +66,7 @@ describe('Dependency Injection Cookbook', function () {
}); });
it('should highlight Hero Bios and Contacts container when mouseover', function () { it('should highlight Hero Bios and Contacts container when mouseover', function () {
let target = element(by.css('div[myHighlight="yellow"]')) let target = element(by.css('div[myHighlight="yellow"]'));
let yellow = 'rgba(255, 255, 0, 1)'; let yellow = 'rgba(255, 255, 0, 1)';
expect(target.getCssValue('background-color')).not.toEqual(yellow); expect(target.getCssValue('background-color')).not.toEqual(yellow);

View File

@ -14,7 +14,7 @@ export class HeroCacheService {
if (!this.hero) { if (!this.hero) {
this.hero = this.heroService.getHeroById(id); this.hero = this.heroService.getHeroById(id);
} }
return this.hero return this.hero;
} }
} }
// #enddocregion service // #enddocregion service

View File

@ -4,10 +4,10 @@ import { Hero } from './hero';
export class HeroData { export class HeroData {
createDb() { createDb() {
let heroes = [ let heroes = [
new Hero(1,"Windstorm"), new Hero(1, 'Windstorm'),
new Hero(2,"Bombasto"), new Hero(2, 'Bombasto'),
new Hero(3,"Magneta"), new Hero(3, 'Magneta'),
new Hero(4,"Tornado") new Hero(4, 'Tornado')
]; ];
return {heroes}; return {heroes};
} }

View File

@ -23,7 +23,7 @@ const provideParent =
// #enddocregion provide-parent, provide-the-parent // #enddocregion provide-parent, provide-the-parent
// #docregion provide-parent // #docregion provide-parent
(component: any, parentType?: any) => { (component: any, parentType?: any) => {
return { provide: parentType || Parent, useExisting: forwardRef(() => component) } return { provide: parentType || Parent, useExisting: forwardRef(() => component) };
}; };
// #enddocregion provide-parent // #enddocregion provide-parent
@ -31,7 +31,7 @@ const provideParent =
const provideTheParent = const provideTheParent =
// #docregion provide-the-parent // #docregion provide-the-parent
(component: any) => { (component: any) => {
return { provide: Parent, useExisting: forwardRef(() => component) } return { provide: Parent, useExisting: forwardRef(() => component) };
}; };
// #enddocregion provide-the-parent // #enddocregion provide-the-parent

View File

@ -15,7 +15,7 @@ describe('Dynamic Form', function () {
emailElement.sendKeys(email); emailElement.sendKeys(email);
expect(emailElement.getAttribute('value')).toEqual(email); expect(emailElement.getAttribute('value')).toEqual(email);
element(by.css('select option[value="solid"]')).click() element(by.css('select option[value="solid"]')).click();
let saveButton = element.all(by.css('button')).get(0); let saveButton = element.all(by.css('button')).get(0);
saveButton.click().then(function(){ saveButton.click().then(function(){

View File

@ -1,5 +1,5 @@
// #docregion // #docregion
import { Component } from '@angular/core' import { Component } from '@angular/core';
import { DynamicForm } from './dynamic-form.component'; import { DynamicForm } from './dynamic-form.component';
import { QuestionService } from './question.service'; import { QuestionService } from './question.service';
@ -16,7 +16,7 @@ import { QuestionService } from './question.service';
providers: [QuestionService] providers: [QuestionService]
}) })
export class AppComponent { export class AppComponent {
questions:any[] questions: any[];
constructor(service: QuestionService) { constructor(service: QuestionService) {
this.questions = service.getQuestions(); this.questions = service.getQuestions();

View File

@ -1,3 +1,4 @@
/* tslint:disable */
// #docregion // #docregion
import { bootstrap } from '@angular/platform-browser-dynamic'; import { bootstrap } from '@angular/platform-browser-dynamic';

View File

@ -10,7 +10,7 @@ import { Component, HostBinding, HostListener } from '@angular/core';
export class HeroesComponent { export class HeroesComponent {
@HostBinding() title = 'Tooltip content'; @HostBinding() title = 'Tooltip content';
@HostBinding('class.heading') @HostBinding('class.heading')
hClass = true hClass = true;
active: boolean; active: boolean;
constructor() {} constructor() {}

View File

@ -34,7 +34,7 @@ class HeroComponent {
active: boolean; active: boolean;
@ContentChild(ActiveLabelComponent) @ContentChild(ActiveLabelComponent)
label:ActiveLabelComponent label: ActiveLabelComponent;
activate() { activate() {
this.active = true; this.active = true;

View File

@ -1,8 +1,6 @@
// #docregion ng2import // #docregion ng2import
import { bootstrap } import { bootstrap }
from '@angular/platform-browser-dynamic'; from '@angular/platform-browser-dynamic';
import {
} from '@angular/router';
import { import {
LocationStrategy, LocationStrategy,
HashLocationStrategy HashLocationStrategy

View File

@ -16,7 +16,7 @@ export class HeroAppComponent {
hero = new Hero( hero = new Hero(
'Human Torch', 'Human Torch',
['Mister Fantastic', 'Invisible Woman', 'Thing'] ['Mister Fantastic', 'Invisible Woman', 'Thing']
) );
@HostBinding('class') get themeClass() { @HostBinding('class') get themeClass() {
return 'theme-light'; return 'theme-light';

View File

@ -123,7 +123,7 @@ describe('Dependency Injection Tests', function () {
it('P10 (optional dependency) displays as expected', function () { it('P10 (optional dependency) displays as expected', function () {
expectedMsg = 'Optional logger was not available'; expectedMsg = 'Optional logger was not available';
expect(element(by.css('#p10')).getText()).toEqual(expectedMsg); expect(element(by.css('#p10')).getText()).toEqual(expectedMsg);
}) });
}); });
describe('User/Heroes:', function() { describe('User/Heroes:', function() {

View File

@ -6,8 +6,8 @@ export let APP_CONFIG = new OpaqueToken('app.config');
// #docregion config // #docregion config
export interface AppConfig { export interface AppConfig {
apiEndpoint: string, apiEndpoint: string;
title: string title: string;
} }
export const HERO_DI_CONFIG: AppConfig = { export const HERO_DI_CONFIG: AppConfig = {

View File

@ -7,7 +7,7 @@ import { Car, Engine, Tires } from './car';
export function simpleCar() { export function simpleCar() {
// #docregion car-ctor-instantiation // #docregion car-ctor-instantiation
// Simple car with 4 cylinders and Flintstone tires. // Simple car with 4 cylinders and Flintstone tires.
var car = new Car(new Engine(), new Tires()); let car = new Car(new Engine(), new Tires());
// #enddocregion car-ctor-instantiation // #enddocregion car-ctor-instantiation
car.description = 'Simple'; car.description = 'Simple';
return car; return car;
@ -23,8 +23,8 @@ export function simpleCar() {
export function superCar() { export function superCar() {
// #docregion car-ctor-instantiation-with-param // #docregion car-ctor-instantiation-with-param
// Super car with 12 cylinders and Flintstone tires. // Super car with 12 cylinders and Flintstone tires.
var bigCylinders = 12; let bigCylinders = 12;
var car = new Car(new Engine2(bigCylinders), new Tires()); let car = new Car(new Engine2(bigCylinders), new Tires());
// #enddocregion car-ctor-instantiation-with-param // #enddocregion car-ctor-instantiation-with-param
car.description = 'Super'; car.description = 'Super';
return car; return car;
@ -33,13 +33,13 @@ export function superCar() {
/////////// example 3 ////////// /////////// example 3 //////////
// #docregion car-ctor-instantiation-with-mocks // #docregion car-ctor-instantiation-with-mocks
class MockEngine extends Engine { cylinders = 8; } class MockEngine extends Engine { cylinders = 8; }
class MockTires extends Tires { make = "YokoGoodStone"; } class MockTires extends Tires { make = 'YokoGoodStone'; }
// #enddocregion car-ctor-instantiation-with-mocks // #enddocregion car-ctor-instantiation-with-mocks
export function testCar() { export function testCar() {
// #docregion car-ctor-instantiation-with-mocks // #docregion car-ctor-instantiation-with-mocks
// Test car with 8 cylinders and YokoGoodStone tires. // Test car with 8 cylinders and YokoGoodStone tires.
var car = new Car(new MockEngine(), new MockTires()); let car = new Car(new MockEngine(), new MockTires());
// #enddocregion car-ctor-instantiation-with-mocks // #enddocregion car-ctor-instantiation-with-mocks
car.description = 'Test'; car.description = 'Test';
return car; return car;

View File

@ -5,23 +5,23 @@ import { Logger } from '../logger.service';
// #docregion injector // #docregion injector
export function useInjector() { export function useInjector() {
var injector: ReflectiveInjector; let injector: ReflectiveInjector;
// #enddocregion injector // #enddocregion injector
/* /*
// #docregion injector-no-new // #docregion injector-no-new
// Cannot instantiate an ReflectiveInjector like this! // Cannot instantiate an ReflectiveInjector like this!
var injector = new ReflectiveInjector([Car, Engine, Tires]); let injector = new ReflectiveInjector([Car, Engine, Tires]);
// #enddocregion injector-no-new // #enddocregion injector-no-new
*/ */
// #docregion injector, injector-create-and-call // #docregion injector, injector-create-and-call
injector = ReflectiveInjector.resolveAndCreate([Car, Engine, Tires]); injector = ReflectiveInjector.resolveAndCreate([Car, Engine, Tires]);
// #docregion injector-call // #docregion injector-call
var car = injector.get(Car); let car = injector.get(Car);
// #enddocregion injector-call, injector-create-and-call // #enddocregion injector-call, injector-create-and-call
car.description = 'Injector'; car.description = 'Injector';
injector = ReflectiveInjector.resolveAndCreate([Logger]); injector = ReflectiveInjector.resolveAndCreate([Logger]);
var logger = injector.get(Logger); let logger = injector.get(Logger);
logger.log('Injector car.drive() said: ' + car.drive()); logger.log('Injector car.drive() said: ' + car.drive());
return car; return car;
} }

View File

@ -18,7 +18,7 @@ export class Car {
// Method using the engine and tires // Method using the engine and tires
drive() { drive() {
return `${this.description} car with ` + return `${this.description} car with ` +
`${this.engine.cylinders} cylinders and ${this.tires.make} tires.` `${this.engine.cylinders} cylinders and ${this.tires.make} tires.`;
} }
} }
// #enddocregion car // #enddocregion car

View File

@ -20,6 +20,6 @@ export class Car {
// Method using the engine and tires // Method using the engine and tires
drive() { drive() {
return `${this.description} car with ` + return `${this.description} car with ` +
`${this.engine.cylinders} cylinders and ${this.tires.make} tires.` `${this.engine.cylinders} cylinders and ${this.tires.make} tires.`;
} }
} }

View File

@ -1,3 +1,4 @@
/* tslint:disable:one-line */
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component } from '@angular/core';

View File

@ -13,7 +13,7 @@ export class HeroService {
// #enddocregion ctor // #enddocregion ctor
getHeroes() { getHeroes() {
this.logger.log('Getting heroes ...') this.logger.log('Getting heroes ...');
return HEROES; return HEROES;
} }
} }

View File

@ -1,3 +1,4 @@
/* tslint:disable:one-line */
// #docregion // #docregion
import { HeroService } from './hero.service'; import { HeroService } from './hero.service';
import { Logger } from '../logger.service'; import { Logger } from '../logger.service';
@ -6,7 +7,7 @@ import { UserService } from '../user.service';
// #docregion factory // #docregion factory
let heroServiceFactory = (logger: Logger, userService: UserService) => { let heroServiceFactory = (logger: Logger, userService: UserService) => {
return new HeroService(logger, userService.user.isAuthorized); return new HeroService(logger, userService.user.isAuthorized);
} };
// #enddocregion factory // #enddocregion factory
// #docregion provider // #docregion provider

View File

@ -2,14 +2,14 @@
import { Hero } from './hero'; import { Hero } from './hero';
export var HEROES: Hero[] = [ export var HEROES: Hero[] = [
{ id: 11, isSecret: false, name: "Mr. Nice" }, { id: 11, isSecret: false, name: 'Mr. Nice' },
{ id: 12, isSecret: false, name: "Narco" }, { id: 12, isSecret: false, name: 'Narco' },
{ id: 13, isSecret: false, name: "Bombasto" }, { id: 13, isSecret: false, name: 'Bombasto' },
{ id: 14, isSecret: false, name: "Celeritas" }, { id: 14, isSecret: false, name: 'Celeritas' },
{ id: 15, isSecret: false, name: "Magneta" }, { id: 15, isSecret: false, name: 'Magneta' },
{ id: 16, isSecret: false, name: "RubberMan" }, { id: 16, isSecret: false, name: 'RubberMan' },
{ id: 17, isSecret: false, name: "Dynama" }, { id: 17, isSecret: false, name: 'Dynama' },
{ id: 18, isSecret: true, name: "Dr IQ" }, { id: 18, isSecret: true, name: 'Dr IQ' },
{ id: 19, isSecret: true, name: "Magma" }, { id: 19, isSecret: true, name: 'Magma' },
{ id: 20, isSecret: true, name: "Tornado" } { id: 20, isSecret: true, name: 'Tornado' }
]; ];

View File

@ -20,8 +20,6 @@ import { Logger } from './logger.service';
providers: [Car, Engine, Tires, heroServiceProvider, Logger] providers: [Car, Engine, Tires, heroServiceProvider, Logger]
}) })
export class InjectorComponent { export class InjectorComponent {
constructor(private injector: Injector) { }
car: Car = this.injector.get(Car); car: Car = this.injector.get(Car);
// #docregion get-hero-service // #docregion get-hero-service
@ -29,8 +27,10 @@ export class InjectorComponent {
// #enddocregion get-hero-service // #enddocregion get-hero-service
hero: Hero = this.heroService.getHeroes()[0]; hero: Hero = this.heroService.getHeroes()[0];
constructor(private injector: Injector) { }
get rodent() { get rodent() {
let rousDontExist = "R.O.U.S.'s? I don't think they exist!"; let rousDontExist = `R.O.U.S.'s? I don't think they exist!`;
return this.injector.get(ROUS, rousDontExist); return this.injector.get(ROUS, rousDontExist);
} }
} }

View File

@ -1,3 +1,4 @@
/* tslint:disable:no-unused-variable */
import { bootstrap } from '@angular/platform-browser-dynamic'; import { bootstrap } from '@angular/platform-browser-dynamic';
import { AppComponent } from './app.component.1'; import { AppComponent } from './app.component.1';
import { HeroService } from './heroes/hero.service.1'; import { HeroService } from './heroes/hero.service.1';
@ -5,9 +6,8 @@ import { HeroService } from './heroes/hero.service.1';
bootstrap(AppComponent); bootstrap(AppComponent);
function discouraged() { function discouraged() {
//#docregion bootstrap // #docregion bootstrap-discouraged
bootstrap(AppComponent, bootstrap(AppComponent,
[HeroService]); // DISCOURAGED (but works)不推荐(但可用) [HeroService]); // DISCOURAGED (but works)
//#enddocregion bootstrap // #enddocregion bootstrap-discouraged
} }

View File

@ -235,9 +235,10 @@ export class ProviderComponent10 {
log: string; log: string;
// #docregion provider-10-ctor // #docregion provider-10-ctor
constructor(@Optional() private logger: Logger) { constructor(@Optional() private logger: Logger) {
if (this.logger) if (this.logger) {
this.logger.log(some_message); this.logger.log(some_message);
} }
}
// #enddocregion provider-10-ctor // #enddocregion provider-10-ctor
ngOnInit() { ngOnInit() {

View File

@ -1,3 +1,4 @@
/* tslint:disable */
// Simulate a simple test // Simulate a simple test
// Reader should look to the testing chapter for the real thing // Reader should look to the testing chapter for the real thing
@ -24,10 +25,10 @@ function runTests() {
let expectedHeroes = [{name: 'A'}, {name: 'B'}] let expectedHeroes = [{name: 'A'}, {name: 'B'}]
let mockService = <HeroService> {getHeroes: () => expectedHeroes } let mockService = <HeroService> {getHeroes: () => expectedHeroes }
it("should have heroes when HeroListComponent created", () => { it('should have heroes when HeroListComponent created', () => {
let hlc = new HeroListComponent(mockService); let hlc = new HeroListComponent(mockService);
expect(hlc.heroes.length).toEqual(expectedHeroes.length); expect(hlc.heroes.length).toEqual(expectedHeroes.length);
}) });
// #enddocregion spec // #enddocregion spec
return testResults; return testResults;
@ -45,7 +46,7 @@ function expect(actual:any) {
{pass: 'passed', message: testName} : {pass: 'passed', message: testName} :
{pass: 'failed', message: `${testName}; expected ${actual} to equal ${expected}.`}; {pass: 'failed', message: `${testName}; expected ${actual} to equal ${expected}.`};
} }
} };
} }
function it(label: string, test: () => void) { function it(label: string, test: () => void) {

View File

@ -4,7 +4,7 @@ import {Injectable} from '@angular/core';
export class User { export class User {
constructor( constructor(
public name: string, public name: string,
public isAuthorized:boolean = false) { } public isAuthorized = false) { }
} }
// Todo: get the user; don't 'new' it. // Todo: get the user; don't 'new' it.

View File

@ -1,3 +1,4 @@
/* tslint:disable */
import { bootstrap } from '@angular/platform-browser-dynamic'; import { bootstrap } from '@angular/platform-browser-dynamic';
import { AppCtorComponent } from './app-ctor.component'; import { AppCtorComponent } from './app-ctor.component';

View File

@ -1,6 +1,6 @@
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { HeroFormComponent } from './hero-form.component' import { HeroFormComponent } from './hero-form.component';
@Component({ @Component({
selector: 'my-app', selector: 'my-app',

View File

@ -7,7 +7,7 @@ describe('Hierarchical dependency injection', function () {
it('should open with a card view', function () { it('should open with a card view', function () {
expect(element.all(by.cssContainingText('button', 'edit')).get(0).isDisplayed()).toBe(true, expect(element.all(by.cssContainingText('button', 'edit')).get(0).isDisplayed()).toBe(true,
"edit button should be displayed"); 'edit button should be displayed');
}); });
it('should have multiple heroes listed', function () { it('should have multiple heroes listed', function () {
@ -17,8 +17,8 @@ describe('Hierarchical dependency injection', function () {
it('should change to editor view after selection', function () { it('should change to editor view after selection', function () {
let editButtonEle = element.all(by.cssContainingText('button', 'edit')).get(0); let editButtonEle = element.all(by.cssContainingText('button', 'edit')).get(0);
editButtonEle.click().then(function() { editButtonEle.click().then(function() {
expect(editButtonEle.isDisplayed()).toBe(false, "edit button should be hidden after selection"); expect(editButtonEle.isDisplayed()).toBe(false, 'edit button should be hidden after selection');
}) });
}); });
it('should be able to save editor change', function () { it('should be able to save editor change', function () {
@ -38,7 +38,7 @@ describe('Hierarchical dependency injection', function () {
editButtonEle.click().then(function() { editButtonEle.click().then(function() {
let inputEle = heroEle.element(by.css('hero-editor input')); let inputEle = heroEle.element(by.css('hero-editor input'));
// return inputEle.sendKeys("foo"); // return inputEle.sendKeys("foo");
return sendKeys(inputEle, "foo"); return sendKeys(inputEle, 'foo');
}).then(function() { }).then(function() {
let buttonName = shouldSave ? 'save' : 'cancel'; let buttonName = shouldSave ? 'save' : 'cancel';
let buttonEle = heroEle.element(by.cssContainingText('button', buttonName)); let buttonEle = heroEle.element(by.cssContainingText('button', buttonName));
@ -49,7 +49,7 @@ describe('Hierarchical dependency injection', function () {
} else { } else {
expect(heroNameEle.getText()).not.toContain('foo'); expect(heroNameEle.getText()).not.toContain('foo');
} }
}) });
} }

View File

@ -1,6 +1,6 @@
// #docregion // #docregion
export class EditItem<T> { export class EditItem<T> {
editing: boolean editing: boolean;
constructor (public item: T) {} constructor (public item: T) {}
} }
// #docregion // #docregion

View File

@ -2,8 +2,8 @@ import { Hero } from './hero';
export class HeroesService { export class HeroesService {
heroes: Array<Hero> = [ heroes: Array<Hero> = [
{ name: "RubberMan", power: 'flexibility'}, { name: 'RubberMan', power: 'flexibility'},
{ name: "Tornado", power: 'Weather changer'} { name: 'Tornado', power: 'Weather changer'}
]; ];
getHeroes () { getHeroes () {

View File

@ -4,7 +4,7 @@ import { bootstrap } from '@angular/platform-browser-dynamic';
import { HeroesListComponent } from './heroes-list.component'; import { HeroesListComponent } from './heroes-list.component';
import { HeroesService } from './heroes.service'; import { HeroesService } from './heroes.service';
bootstrap(HeroesListComponent, [HeroesService]) bootstrap(HeroesListComponent, [HeroesService]);
/* Documentation artifact below /* Documentation artifact below
// #docregion bad-alternative // #docregion bad-alternative

View File

@ -1,6 +1,6 @@
// #docregion // #docregion
// Declare an interaface for type safety // Declare an interaface for type safety
export interface Todo { export interface Todo {
text: string, text: string;
done: boolean done: boolean;
} }

View File

@ -1,5 +1,6 @@
// #docregion // #docregion
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { Todo } from './todo'; import { Todo } from './todo';
@Component({ @Component({

View File

@ -11,22 +11,22 @@ describe('Lifecycle hooks', function () {
it('should support peek-a-boo', function () { it('should support peek-a-boo', function () {
let pabComp = element(by.css('peek-a-boo-parent peek-a-boo')); let pabComp = element(by.css('peek-a-boo-parent peek-a-boo'));
expect(pabComp.isPresent()).toBe(false, "should not be able to find the 'peek-a-boo' component"); expect(pabComp.isPresent()).toBe(false, 'should not be able to find the "peek-a-boo" component');
let pabButton = element.all(by.css('peek-a-boo-parent button')).get(0); let pabButton = element.all(by.css('peek-a-boo-parent button')).get(0);
let updateHeroButton = element.all(by.css('peek-a-boo-parent button')).get(1); let updateHeroButton = element.all(by.css('peek-a-boo-parent button')).get(1);
expect(pabButton.getText()).toContain('Create Peek'); expect(pabButton.getText()).toContain('Create Peek');
pabButton.click().then(function () { pabButton.click().then(function () {
expect(pabButton.getText()).toContain('Destroy Peek'); expect(pabButton.getText()).toContain('Destroy Peek');
expect(pabComp.isDisplayed()).toBe(true, "should be able to see the 'peek-a-boo' component"); expect(pabComp.isDisplayed()).toBe(true, 'should be able to see the "peek-a-boo" component');
expect(pabComp.getText()).toContain('Windstorm'); expect(pabComp.getText()).toContain('Windstorm');
expect(pabComp.getText()).not.toContain('Windstorm!'); expect(pabComp.getText()).not.toContain('Windstorm!');
expect(updateHeroButton.isPresent()).toBe(true, "should be able to see the update hero button"); expect(updateHeroButton.isPresent()).toBe(true, 'should be able to see the update hero button');
return updateHeroButton.click(); return updateHeroButton.click();
}).then(function () { }).then(function () {
expect(pabComp.getText()).toContain('Windstorm!'); expect(pabComp.getText()).toContain('Windstorm!');
return pabButton.click(); return pabButton.click();
}).then(function () { }).then(function () {
expect(pabComp.isPresent()).toBe(false, "should no longer be able to find the 'peek-a-boo' component"); expect(pabComp.isPresent()).toBe(false, 'should no longer be able to find the "peek-a-boo" component');
}); });
}); });
@ -39,18 +39,18 @@ describe('Lifecycle hooks', function () {
let changeLogEles = onChangesViewEle.all(by.css('div')); let changeLogEles = onChangesViewEle.all(by.css('div'));
expect(titleEle.getText()).toContain('Windstorm can sing'); expect(titleEle.getText()).toContain('Windstorm can sing');
expect(changeLogEles.count()).toEqual(2, "should start with 2 messages"); expect(changeLogEles.count()).toEqual(2, 'should start with 2 messages');
// heroNameInputEle.sendKeys('-foo-').then(function () { // heroNameInputEle.sendKeys('-foo-').then(function () {
sendKeys(heroNameInputEle, '-foo-').then(function () { sendKeys(heroNameInputEle, '-foo-').then(function () {
expect(titleEle.getText()).toContain('Windstorm-foo- can sing'); expect(titleEle.getText()).toContain('Windstorm-foo- can sing');
expect(changeLogEles.count()).toEqual(2, "should still have 2 messages"); expect(changeLogEles.count()).toEqual(2, 'should still have 2 messages');
// protractor bug with sendKeys means that line below does not work. // protractor bug with sendKeys means that line below does not work.
// return powerInputEle.sendKeys('-bar-'); // return powerInputEle.sendKeys('-bar-');
return sendKeys(powerInputEle, '-bar-'); return sendKeys(powerInputEle, '-bar-');
}).then(function () { }).then(function () {
expect(titleEle.getText()).toContain('Windstorm-foo- can sing-bar-'); expect(titleEle.getText()).toContain('Windstorm-foo- can sing-bar-');
// 7 == 2 previously + length of '-bar-' // 7 == 2 previously + length of '-bar-'
expect(changeLogEles.count()).toEqual(7, "should have 7 messages now"); expect(changeLogEles.count()).toEqual(7, 'should have 7 messages now');
}); });
}); });
@ -66,16 +66,16 @@ describe('Lifecycle hooks', function () {
expect(titleEle.getText()).toContain('Windstorm can sing'); expect(titleEle.getText()).toContain('Windstorm can sing');
changeLogEles.count().then(function(count) { changeLogEles.count().then(function(count) {
// Empirically 5 messages to start // Empirically 5 messages to start
expect(count).toBeGreaterThan(4, "should start with some messages"); expect(count).toBeGreaterThan(4, 'should start with some messages');
logCount = count; logCount = count;
// heroNameInputEle.sendKeys('-foo-').then(function () { // heroNameInputEle.sendKeys('-foo-').then(function () {
return sendKeys(heroNameInputEle, '-foo-') return sendKeys(heroNameInputEle, '-foo-');
}).then(function () { }).then(function () {
expect(titleEle.getText()).toContain('Windstorm-foo- can sing'); expect(titleEle.getText()).toContain('Windstorm-foo- can sing');
return changeLogEles.count() return changeLogEles.count();
}).then(function (count) { }).then(function (count) {
// two more for each keystroke except the 1st // two more for each keystroke except the 1st
expect(count).toEqual(logCount + 9, 'should add 9 more messages') expect(count).toEqual(logCount + 9, 'should add 9 more messages');
logCount = count; logCount = count;
// return powerInputEle.sendKeys('-bar-'); // return powerInputEle.sendKeys('-bar-');
return sendKeys(powerInputEle, '-bar-'); return sendKeys(powerInputEle, '-bar-');
@ -99,18 +99,18 @@ describe('Lifecycle hooks', function () {
logEles.count().then(function(count) { logEles.count().then(function(count) {
logCount = count; logCount = count;
return sendKeys(childViewInputEle, "-test-"); return sendKeys(childViewInputEle, '-test-');
}).then(function() { }).then(function() {
expect(childViewInputEle.getAttribute('value')).toContain('-test-'); expect(childViewInputEle.getAttribute('value')).toContain('-test-');
expect(commentEle.isPresent()).toBe(true, 'should have comment because >10 chars'); expect(commentEle.isPresent()).toBe(true, 'should have comment because >10 chars');
expect(commentEle.getText()).toContain('long name'); expect(commentEle.getText()).toContain('long name');
return logEles.count(); return logEles.count();
}).then(function(count) { }).then(function(count) {
expect(logCount + 10).toEqual(count, "10 additional log messages should have been added"); expect(logCount + 10).toEqual(count, '10 additional log messages should have been added');
logCount = count; logCount = count;
return buttonEle.click(); return buttonEle.click();
}).then(function() { }).then(function() {
expect(logEles.count()).toBeLessThan(logCount, "log should shrink after reset"); expect(logEles.count()).toBeLessThan(logCount, 'log should shrink after reset');
}); });
}); });
@ -128,18 +128,18 @@ describe('Lifecycle hooks', function () {
logEles.count().then(function(count) { logEles.count().then(function(count) {
logCount = count; logCount = count;
return sendKeys(childViewInputEle, "-test-"); return sendKeys(childViewInputEle, '-test-');
}).then(function() { }).then(function() {
expect(childViewInputEle.getAttribute('value')).toContain('-test-'); expect(childViewInputEle.getAttribute('value')).toContain('-test-');
expect(commentEle.isPresent()).toBe(true, 'should have comment because >10 chars'); expect(commentEle.isPresent()).toBe(true, 'should have comment because >10 chars');
expect(commentEle.getText()).toContain('long name'); expect(commentEle.getText()).toContain('long name');
return logEles.count(); return logEles.count();
}).then(function(count) { }).then(function(count) {
expect(logCount + 10).toEqual(count, "10 additional log messages should have been added"); expect(logCount + 10).toEqual(count, '10 additional log messages should have been added');
logCount = count; logCount = count;
return buttonEle.click(); return buttonEle.click();
}).then(function() { }).then(function() {
expect(logEles.count()).toBeLessThan(logCount, "log should shrink after reset"); expect(logEles.count()).toBeLessThan(logCount, 'log should shrink after reset');
}); });
}); });
@ -151,7 +151,7 @@ describe('Lifecycle hooks', function () {
let logEles = element.all(by.css('spy-parent h4 ~ div')); let logEles = element.all(by.css('spy-parent h4 ~ div'));
expect(heroEles.count()).toBe(2, 'should have two heroes displayed'); expect(heroEles.count()).toBe(2, 'should have two heroes displayed');
expect(logEles.count()).toBe(2, 'should have two log entries'); expect(logEles.count()).toBe(2, 'should have two log entries');
sendKeys(inputEle, "-test-").then(function() { sendKeys(inputEle, '-test-').then(function() {
return addHeroButtonEle.click(); return addHeroButtonEle.click();
}).then(function() { }).then(function() {
expect(heroEles.count()).toBe(3, 'should have added one hero'); expect(heroEles.count()).toBe(3, 'should have added one hero');
@ -161,7 +161,7 @@ describe('Lifecycle hooks', function () {
}).then(function() { }).then(function() {
expect(heroEles.count()).toBe(0, 'should no longer have any heroes'); expect(heroEles.count()).toBe(0, 'should no longer have any heroes');
expect(logEles.count()).toBe(7, 'should now have 7 log entries - 3 orig + 1 reset + 3 removeall'); expect(logEles.count()).toBe(7, 'should now have 7 log entries - 3 orig + 1 reset + 3 removeall');
}) });
}); });
it('should support "spy counter"', function () { it('should support "spy counter"', function () {
@ -178,8 +178,6 @@ describe('Lifecycle hooks', function () {
}).then(function() { }).then(function() {
expect(textEle.getText()).toContain('Counter = 0'); expect(textEle.getText()).toContain('Counter = 0');
expect(logEles.count()).toBe(7, 'should now have 7 log entries - 3 prev + 1 reset + 2 destroy + 1 init'); expect(logEles.count()).toBe(7, 'should now have 7 log entries - 3 prev + 1 reset + 2 destroy + 1 init');
})
}); });
});
}); });

View File

@ -63,7 +63,7 @@ export class AfterContentComponent implements AfterContentChecked, AfterContentI
// This surrogate for real business logic sets the `comment` // This surrogate for real business logic sets the `comment`
private doSomething() { private doSomething() {
this.comment = this.contentChild.hero.length > 10 ? 'That\'s a long name' : ''; this.comment = this.contentChild.hero.length > 10 ? `That's a long name` : '';
} }
private logIt(method: string) { private logIt(method: string) {

View File

@ -67,7 +67,7 @@ export class AfterViewComponent implements AfterViewChecked, AfterViewInit {
// #docregion do-something // #docregion do-something
// This surrogate for real business logic sets the `comment` // This surrogate for real business logic sets the `comment`
private doSomething() { private doSomething() {
let c = this.viewChild.hero.length > 10 ? "That's a long name" : ''; let c = this.viewChild.hero.length > 10 ? `That's a long name` : '';
if (c !== this.comment) { if (c !== this.comment) {
// Wait a tick because the component's view has already been checked // Wait a tick because the component's view has already been checked
this.logger.tick_then(() => this.comment = c); this.logger.tick_then(() => this.comment = c);
@ -77,7 +77,7 @@ export class AfterViewComponent implements AfterViewChecked, AfterViewInit {
private logIt(method: string) { private logIt(method: string) {
let child = this.viewChild; let child = this.viewChild;
let message = `${method}: ${child ? child.hero:'no'} child view` let message = `${method}: ${child ? child.hero : 'no'} child view`;
this.logger.log(message); this.logger.log(message);
} }
// #docregion hooks // #docregion hooks

View File

@ -7,7 +7,7 @@ describe('Pipes', function () {
it('should open correctly', function () { it('should open correctly', function () {
expect(element.all(by.tagName('h1')).get(0).getText()).toEqual('Pipes'); expect(element.all(by.tagName('h1')).get(0).getText()).toEqual('Pipes');
expect(element(by.css('hero-birthday p')).getText()).toEqual("The hero's birthday is Apr 15, 1988"); expect(element(by.css('hero-birthday p')).getText()).toEqual(`The hero's birthday is Apr 15, 1988`);
}); });
it('should show 4 heroes', function () { it('should show 4 heroes', function () {
@ -19,23 +19,23 @@ describe('Pipes', function () {
}); });
it('should show alternate birthday formats', function () { it('should show alternate birthday formats', function () {
expect(element(by.cssContainingText('my-app > p', "The hero's birthday is Apr 15, 1988")).isDisplayed()).toBe(true); expect(element(by.cssContainingText('my-app > p', `The hero's birthday is Apr 15, 1988`)).isDisplayed()).toBe(true);
expect(element(by.cssContainingText('my-app > p', "The hero's birthday is 04/15/88")).isDisplayed()).toBe(true); expect(element(by.cssContainingText('my-app > p', `The hero's birthday is 04/15/88`)).isDisplayed()).toBe(true);
}); });
it('should be able to toggle birthday formats', function () { it('should be able to toggle birthday formats', function () {
let birthDayEle = element(by.css('hero-birthday2 > p')); let birthDayEle = element(by.css('hero-birthday2 > p'));
expect(birthDayEle.getText()).toEqual("The hero's birthday is 4/15/1988"); expect(birthDayEle.getText()).toEqual(`The hero's birthday is 4/15/1988`);
let buttonEle = element(by.cssContainingText('hero-birthday2 > button', "Toggle Format")); let buttonEle = element(by.cssContainingText('hero-birthday2 > button', 'Toggle Format'));
expect(buttonEle.isDisplayed()).toBe(true); expect(buttonEle.isDisplayed()).toBe(true);
buttonEle.click().then(function() { buttonEle.click().then(function() {
expect(birthDayEle.getText()).toEqual("The hero's birthday is Friday, April 15, 1988"); expect(birthDayEle.getText()).toEqual(`The hero's birthday is Friday, April 15, 1988`);
}); });
}); });
it('should be able to chain and compose pipes', function () { it('should be able to chain and compose pipes', function () {
let chainedPipeEles = element.all(by.cssContainingText('my-app p', "The chained hero's")); let chainedPipeEles = element.all(by.cssContainingText('my-app p', `The chained hero's`));
expect(chainedPipeEles.count()).toBe(3, "should have 3 chained pipe examples"); expect(chainedPipeEles.count()).toBe(3, 'should have 3 chained pipe examples');
expect(chainedPipeEles.get(0).getText()).toContain('APR 15, 1988'); expect(chainedPipeEles.get(0).getText()).toContain('APR 15, 1988');
expect(chainedPipeEles.get(1).getText()).toContain('FRIDAY, APRIL 15, 1988'); expect(chainedPipeEles.get(1).getText()).toContain('FRIDAY, APRIL 15, 1988');
expect(chainedPipeEles.get(2).getText()).toContain('FRIDAY, APRIL 15, 1988'); expect(chainedPipeEles.get(2).getText()).toContain('FRIDAY, APRIL 15, 1988');
@ -52,13 +52,13 @@ describe('Pipes', function () {
let factorInputEle = eles.get(1); let factorInputEle = eles.get(1);
let outputEle = element(by.css('power-boost-calculator p')); let outputEle = element(by.css('power-boost-calculator p'));
baseInputEle.clear().then(function() { baseInputEle.clear().then(function() {
return sendKeys(baseInputEle, "7"); return sendKeys(baseInputEle, '7');
}).then(function() { }).then(function() {
return factorInputEle.clear(); return factorInputEle.clear();
}).then(function() { }).then(function() {
return sendKeys(factorInputEle, "3"); return sendKeys(factorInputEle, '3');
}).then(function() { }).then(function() {
expect(outputEle.getText()).toContain("343"); expect(outputEle.getText()).toContain('343');
}); });
}); });
@ -74,13 +74,13 @@ describe('Pipes', function () {
expect(mutateCheckEle.getAttribute('checked')).toEqual('true', 'should default to mutating array'); expect(mutateCheckEle.getAttribute('checked')).toEqual('true', 'should default to mutating array');
expect(flyingHeroesEle.count()).toEqual(2, 'only two of the original heroes can fly'); expect(flyingHeroesEle.count()).toEqual(2, 'only two of the original heroes can fly');
return sendKeys(nameEle, "test1\n") return sendKeys(nameEle, 'test1\n')
.then(function(){ .then(function(){
expect(flyingHeroesEle.count()).toEqual(2, 'no change while mutating array'); expect(flyingHeroesEle.count()).toEqual(2, 'no change while mutating array');
return mutateCheckEle.click(); return mutateCheckEle.click();
}) })
.then(function() { .then(function() {
return sendKeys(nameEle, "test2\n"); return sendKeys(nameEle, 'test2\n');
}) })
.then(function() { .then(function() {
expect(flyingHeroesEle.count()).toEqual(4, 'not mutating; should see both adds'); expect(flyingHeroesEle.count()).toEqual(4, 'not mutating; should see both adds');
@ -90,7 +90,7 @@ describe('Pipes', function () {
}) })
.then(function() { .then(function() {
expect(flyingHeroesEle.count()).toEqual(2, 'reset should restore orginal flying heroes'); expect(flyingHeroesEle.count()).toEqual(2, 'reset should restore orginal flying heroes');
}) });
}); });
@ -98,17 +98,16 @@ describe('Pipes', function () {
let nameEle = element(by.css('flying-heroes-impure input[type="text"]')); let nameEle = element(by.css('flying-heroes-impure input[type="text"]'));
let canFlyCheckEle = element(by.css('flying-heroes-impure #can-fly')); let canFlyCheckEle = element(by.css('flying-heroes-impure #can-fly'));
let mutateCheckEle = element(by.css('flying-heroes-impure #mutate')); let mutateCheckEle = element(by.css('flying-heroes-impure #mutate'));
let resetEle = element(by.css('flying-heroes-impure button'));
let flyingHeroesEle = element.all(by.css('flying-heroes-impure #flyers div')); let flyingHeroesEle = element.all(by.css('flying-heroes-impure #flyers div'));
expect(canFlyCheckEle.getAttribute('checked')).toEqual('true', 'should default to "can fly"'); expect(canFlyCheckEle.getAttribute('checked')).toEqual('true', 'should default to "can fly"');
expect(mutateCheckEle.getAttribute('checked')).toEqual('true', 'should default to mutating array'); expect(mutateCheckEle.getAttribute('checked')).toEqual('true', 'should default to mutating array');
expect(flyingHeroesEle.count()).toEqual(2, 'only two of the original heroes can fly'); expect(flyingHeroesEle.count()).toEqual(2, 'only two of the original heroes can fly');
return sendKeys(nameEle, "test1\n") return sendKeys(nameEle, 'test1\n')
.then(function(){ .then(function(){
expect(flyingHeroesEle.count()).toEqual(3, 'new flying hero should show in mutating array'); expect(flyingHeroesEle.count()).toEqual(3, 'new flying hero should show in mutating array');
}) });
}); });
it('should show an async hero message', function () { it('should show an async hero message', function () {

View File

@ -33,7 +33,7 @@ export class FlyingHeroesComponent {
// Impure pipe will display // Impure pipe will display
// #docregion v1 // #docregion v1
// #docregion push // #docregion push
this.heroes.push(hero) this.heroes.push(hero);
// #enddocregion push // #enddocregion push
// #enddocregion v1 // #enddocregion v1
} else { } else {

View File

@ -12,6 +12,12 @@ import { Observable } from 'rxjs/Rx';
export class HeroAsyncMessageComponent { export class HeroAsyncMessageComponent {
message$: Observable<string>; message$: Observable<string>;
private messages = [
'You are my hero!',
'You are the best hero!',
'Will you be my hero?'
];
constructor() { this.resend(); } constructor() { this.resend(); }
resend() { resend() {
@ -19,12 +25,6 @@ export class HeroAsyncMessageComponent {
.map(i => this.messages[i]) .map(i => this.messages[i])
.take(this.messages.length); .take(this.messages.length);
} }
private messages = [
'You are my hero!',
'You are the best hero!',
'Will you be my hero?'
];
} }
// #enddocregion // #enddocregion

View File

@ -1,5 +1,5 @@
// #docregion // #docregion
import { Component } from '@angular/core' import { Component } from '@angular/core';
@Component({ @Component({
selector: 'hero-birthday', selector: 'hero-birthday',

View File

@ -1,5 +1,5 @@
// #docregion // #docregion
import { Component } from '@angular/core' import { Component } from '@angular/core';
@Component({ @Component({
selector: 'hero-birthday2', selector: 'hero-birthday2',
@ -15,6 +15,6 @@ export class HeroBirthday2 {
birthday = new Date(1988, 3, 15); // April 15, 1988 birthday = new Date(1988, 3, 15); // April 15, 1988
toggle = true; // start with true == shortDate toggle = true; // start with true == shortDate
get format() { return this.toggle ? 'shortDate' : 'fullDate'} get format() { return this.toggle ? 'shortDate' : 'fullDate'; }
toggleFormat() { this.toggle = !this.toggle; } toggleFormat() { this.toggle = !this.toggle; }
} }

View File

@ -1,7 +1,7 @@
export interface Flyer { canFly: boolean } export interface Flyer { canFly: boolean; }
export const HEROES = [ export const HEROES = [
{"name": "Windstorm", "canFly": true}, {name: 'Windstorm', canFly: true},
{"name": "Bombasto", "canFly": false}, {name: 'Bombasto', canFly: false},
{"name": "Magneto", "canFly": false}, {name: 'Magneto', canFly: false},
{"name": "Tornado", "canFly": true} {name: 'Tornado', canFly: true}
]; ];

View File

@ -23,36 +23,36 @@ describe('Router', function () {
heroDetail: element(by.css('my-app > undefined > div')), heroDetail: element(by.css('my-app > undefined > div')),
heroDetailTitle: element(by.css('my-app > undefined > div > h3')), heroDetailTitle: element(by.css('my-app > undefined > div > h3')),
} };
} }
it('should be able to see the start screen', function () { it('should be able to see the start screen', function () {
let page = getPageStruct(); let page = getPageStruct();
expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices'); expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices');
expect(page.crisisHref.getText()).toEqual("Crisis Center"); expect(page.crisisHref.getText()).toEqual('Crisis Center');
expect(page.heroesHref.getText()).toEqual("Heroes"); expect(page.heroesHref.getText()).toEqual('Heroes');
}); });
it('should be able to see crises center items', function () { it('should be able to see crises center items', function () {
let page = getPageStruct(); let page = getPageStruct();
expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries at start"); expect(page.crisisList.count()).toBe(4, 'should be 4 crisis center entries at start');
}); });
it('should be able to see hero items', function () { it('should be able to see hero items', function () {
let page = getPageStruct(); let page = getPageStruct();
page.heroesHref.click().then(function() { page.heroesHref.click().then(function() {
expect(page.routerTitle.getText()).toContain('HEROES'); expect(page.routerTitle.getText()).toContain('HEROES');
expect(page.heroesList.count()).toBe(6, "should be 6 heroes"); expect(page.heroesList.count()).toBe(6, 'should be 6 heroes');
}); });
}); });
it('should be able to toggle the views', function () { it('should be able to toggle the views', function () {
let page = getPageStruct(); let page = getPageStruct();
page.crisisHref.click().then(function() { page.crisisHref.click().then(function() {
expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries"); expect(page.crisisList.count()).toBe(4, 'should be 4 crisis center entries');
return page.heroesHref.click(); return page.heroesHref.click();
}).then(function() { }).then(function() {
expect(page.heroesList.count()).toBe(6, "should be 6 heroes"); expect(page.heroesList.count()).toBe(6, 'should be 6 heroes');
}); });
}); });
@ -77,7 +77,7 @@ describe('Router', function () {
heroText = text.substr(text.indexOf(' ')).trim(); heroText = text.substr(text.indexOf(' ')).trim();
return heroEle.click(); return heroEle.click();
}).then(function() { }).then(function() {
expect(page.heroesList.count()).toBe(0, "should no longer see crisis center entries"); expect(page.heroesList.count()).toBe(0, 'should no longer see crisis center entries');
expect(page.heroDetail.isPresent()).toBe(true, 'should be able to see crisis detail'); expect(page.heroDetail.isPresent()).toBe(true, 'should be able to see crisis detail');
expect(page.heroDetailTitle.getText()).toContain(heroText); expect(page.heroDetailTitle.getText()).toContain(heroText);
let inputEle = page.heroDetail.element(by.css('input')); let inputEle = page.heroDetail.element(by.css('input'));
@ -88,7 +88,7 @@ describe('Router', function () {
return buttonEle.click(); return buttonEle.click();
}).then(function() { }).then(function() {
expect(heroEle.getText()).toContain(heroText + '-foo'); expect(heroEle.getText()).toContain(heroText + '-foo');
}) });
}); });
function crisisCenterEdit(index: number, shouldSave: boolean) { function crisisCenterEdit(index: number, shouldSave: boolean) {
@ -105,7 +105,7 @@ describe('Router', function () {
crisisText = text.substr(text.indexOf(' ')).trim(); crisisText = text.substr(text.indexOf(' ')).trim();
return crisisEle.click(); return crisisEle.click();
}).then(function () { }).then(function () {
expect(page.crisisList.count()).toBe(0, "should no longer see crisis center entries"); expect(page.crisisList.count()).toBe(0, 'should no longer see crisis center entries');
expect(page.crisisDetail.isPresent()).toBe(true, 'should be able to see crisis detail'); expect(page.crisisDetail.isPresent()).toBe(true, 'should be able to see crisis detail');
expect(page.crisisDetailTitle.getText()).toContain(crisisText); expect(page.crisisDetailTitle.getText()).toContain(crisisText);
let inputEle = page.crisisDetail.element(by.css('input')); let inputEle = page.crisisDetail.element(by.css('input'));

View File

@ -1,5 +1,4 @@
// #docplaster // #docplaster
// #docregion // #docregion
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
@ -30,12 +29,12 @@ export class CrisisService {
// #docregion // #docregion
} }
var crises = [ let crises = [
new Crisis(1, 'Dragon Burning Cities'), new Crisis(1, 'Dragon Burning Cities'),
new Crisis(2, 'Sky Rains Great White Sharks'), new Crisis(2, 'Sky Rains Great White Sharks'),
new Crisis(3, 'Giant Asteroid Heading For Earth'), new Crisis(3, 'Giant Asteroid Heading For Earth'),
new Crisis(4, 'Procrastinators Meeting Delayed Again'), new Crisis(4, 'Procrastinators Meeting Delayed Again'),
]; ];
var crisesPromise = Promise.resolve(crises); let crisesPromise = Promise.resolve(crises);
// #enddocregion // #enddocregion

View File

@ -30,7 +30,7 @@ export class HeroListComponent implements OnInit {
// #enddocregion ctor // #enddocregion ctor
ngOnInit() { ngOnInit() {
this.service.getHeroes().then(heroes => this.heroes = heroes) this.service.getHeroes().then(heroes => this.heroes = heroes);
} }
// #docregion select // #docregion select

View File

@ -50,7 +50,7 @@ export class HeroListComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.service.getHeroes().then(heroes => this.heroes = heroes) this.service.getHeroes().then(heroes => this.heroes = heroes);
} }
} }
// #enddocregion // #enddocregion

View File

@ -15,7 +15,7 @@ export class HeroService {
} }
} }
var HEROES = [ let HEROES = [
new Hero(11, 'Mr. Nice'), new Hero(11, 'Mr. Nice'),
new Hero(12, 'Narco'), new Hero(12, 'Narco'),
new Hero(13, 'Bombasto'), new Hero(13, 'Bombasto'),
@ -24,4 +24,4 @@ var HEROES = [
new Hero(16, 'RubberMan') new Hero(16, 'RubberMan')
]; ];
var heroesPromise = Promise.resolve(HEROES); let heroesPromise = Promise.resolve(HEROES);

View File

@ -23,36 +23,36 @@ describe('Router', function () {
heroDetail: element(by.css('my-app > undefined > div')), heroDetail: element(by.css('my-app > undefined > div')),
heroDetailTitle: element(by.css('my-app > undefined > div > h3')), heroDetailTitle: element(by.css('my-app > undefined > div > h3')),
} };
} }
it('should be able to see the start screen', function () { it('should be able to see the start screen', function () {
let page = getPageStruct(); let page = getPageStruct();
expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices'); expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices');
expect(page.crisisHref.getText()).toEqual("Crisis Center"); expect(page.crisisHref.getText()).toEqual('Crisis Center');
expect(page.heroesHref.getText()).toEqual("Heroes"); expect(page.heroesHref.getText()).toEqual('Heroes');
}); });
it('should be able to see crises center items', function () { it('should be able to see crises center items', function () {
let page = getPageStruct(); let page = getPageStruct();
expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries at start"); expect(page.crisisList.count()).toBe(4, 'should be 4 crisis center entries at start');
}); });
it('should be able to see hero items', function () { it('should be able to see hero items', function () {
let page = getPageStruct(); let page = getPageStruct();
page.heroesHref.click().then(function() { page.heroesHref.click().then(function() {
expect(page.routerTitle.getText()).toContain('HEROES'); expect(page.routerTitle.getText()).toContain('HEROES');
expect(page.heroesList.count()).toBe(6, "should be 6 heroes"); expect(page.heroesList.count()).toBe(6, 'should be 6 heroes');
}); });
}); });
it('should be able to toggle the views', function () { it('should be able to toggle the views', function () {
let page = getPageStruct(); let page = getPageStruct();
page.crisisHref.click().then(function() { page.crisisHref.click().then(function() {
expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries"); expect(page.crisisList.count()).toBe(4, 'should be 4 crisis center entries');
return page.heroesHref.click(); return page.heroesHref.click();
}).then(function() { }).then(function() {
expect(page.heroesList.count()).toBe(6, "should be 6 heroes"); expect(page.heroesList.count()).toBe(6, 'should be 6 heroes');
}); });
}); });
@ -77,7 +77,7 @@ describe('Router', function () {
heroText = text.substr(text.indexOf(' ')).trim(); heroText = text.substr(text.indexOf(' ')).trim();
return heroEle.click(); return heroEle.click();
}).then(function() { }).then(function() {
expect(page.heroesList.count()).toBe(0, "should no longer see crisis center entries"); expect(page.heroesList.count()).toBe(0, 'should no longer see crisis center entries');
expect(page.heroDetail.isPresent()).toBe(true, 'should be able to see crisis detail'); expect(page.heroDetail.isPresent()).toBe(true, 'should be able to see crisis detail');
expect(page.heroDetailTitle.getText()).toContain(heroText); expect(page.heroDetailTitle.getText()).toContain(heroText);
let inputEle = page.heroDetail.element(by.css('input')); let inputEle = page.heroDetail.element(by.css('input'));
@ -88,7 +88,7 @@ describe('Router', function () {
return buttonEle.click(); return buttonEle.click();
}).then(function() { }).then(function() {
expect(heroEle.getText()).toContain(heroText + '-foo'); expect(heroEle.getText()).toContain(heroText + '-foo');
}) });
}); });
function crisisCenterEdit(index: number, shouldSave: boolean) { function crisisCenterEdit(index: number, shouldSave: boolean) {
@ -105,7 +105,7 @@ describe('Router', function () {
crisisText = text.substr(text.indexOf(' ')).trim(); crisisText = text.substr(text.indexOf(' ')).trim();
return crisisEle.click(); return crisisEle.click();
}).then(function () { }).then(function () {
expect(page.crisisList.count()).toBe(0, "should no longer see crisis center entries"); expect(page.crisisList.count()).toBe(0, 'should no longer see crisis center entries');
expect(page.crisisDetail.isPresent()).toBe(true, 'should be able to see crisis detail'); expect(page.crisisDetail.isPresent()).toBe(true, 'should be able to see crisis detail');
expect(page.crisisDetailTitle.getText()).toContain(crisisText); expect(page.crisisDetailTitle.getText()).toContain(crisisText);
let inputEle = page.crisisDetail.element(by.css('input')); let inputEle = page.crisisDetail.element(by.css('input'));

View File

@ -29,7 +29,7 @@ export class HeroListComponent implements OnInit {
// #enddocregion ctor // #enddocregion ctor
ngOnInit() { ngOnInit() {
this.service.getHeroes().then(heroes => this.heroes = heroes) this.service.getHeroes().then(heroes => this.heroes = heroes);
} }
// #docregion select // #docregion select

View File

@ -29,7 +29,7 @@ describe('Server Communication', function () {
addButton.click().then(function() { addButton.click().then(function() {
expect(heroTags.count()).toBe(initialHeroCount, 'No new hero should be added'); expect(heroTags.count()).toBe(initialHeroCount, 'No new hero should be added');
}); });
}) });
it('should add a new hero to the list', function () { it('should add a new hero to the list', function () {
expect(heroNameInput).toBeDefined('<input> for hero name must exist'); expect(heroNameInput).toBeDefined('<input> for hero name must exist');
@ -40,7 +40,7 @@ describe('Server Communication', function () {
let newHeroInList = heroTags.get(heroCountAfterAdd - 1).getText(); let newHeroInList = heroTags.get(heroCountAfterAdd - 1).getText();
expect(newHeroInList).toBe(newHeroName, 'The hero should be added to the end of the list'); expect(newHeroInList).toBe(newHeroName, 'The hero should be added to the end of the list');
}); });
}) });
}); });
describe('Wikipedia Demo', function () { describe('Wikipedia Demo', function () {
@ -71,7 +71,7 @@ describe('Server Communication', function () {
}); });
function testForRefreshedResult(keyPressed: string, done: () => void) { function testForRefreshedResult(keyPressed: string, done: () => void) {
testForResult('my-wiki', keyPressed, false, done) testForResult('my-wiki', keyPressed, false, done);
} }
}); });
@ -102,11 +102,11 @@ describe('Server Communication', function () {
function testForNewResult(keyPressed: string, done: () => void) { function testForNewResult(keyPressed: string, done: () => void) {
testForResult('my-wiki-smart', keyPressed, false, done) testForResult('my-wiki-smart', keyPressed, false, done);
} }
function testForStaleResult(keyPressed: string, done: () => void) { function testForStaleResult(keyPressed: string, done: () => void) {
testForResult('my-wiki-smart', keyPressed, true, done) testForResult('my-wiki-smart', keyPressed, true, done);
} }
}); });

View File

@ -11,13 +11,12 @@ import { HeroService } from './hero.service.promise';
}) })
// #docregion component // #docregion component
export class HeroListPromiseComponent implements OnInit { export class HeroListPromiseComponent implements OnInit {
constructor (private heroService: HeroService) {}
errorMessage: string; errorMessage: string;
heroes: Hero[]; heroes: Hero[];
mode = 'Promise'; mode = 'Promise';
constructor (private heroService: HeroService) {}
ngOnInit() { this.getHeroes(); } ngOnInit() { this.getHeroes(); }
// #docregion methods // #docregion methods

View File

@ -11,13 +11,12 @@ import { HeroService } from './hero.service';
}) })
// #docregion component // #docregion component
export class HeroListComponent implements OnInit { export class HeroListComponent implements OnInit {
constructor (private heroService: HeroService) {}
errorMessage: string; errorMessage: string;
heroes: Hero[]; heroes: Hero[];
mode = 'Observable'; mode = 'Observable';
constructor (private heroService: HeroService) {}
ngOnInit() { this.getHeroes(); } ngOnInit() { this.getHeroes(); }
// #docregion methods // #docregion methods

View File

@ -8,11 +8,11 @@ import { Hero } from './hero';
@Injectable() @Injectable()
export class HeroService { export class HeroService {
constructor (private http: Http) {}
// URL to web api // URL to web api
private heroesUrl = 'app/heroes.json'; private heroesUrl = 'app/heroes.json';
constructor (private http: Http) {}
// #docregion methods // #docregion methods
getHeroes (): Promise<Hero[]> { getHeroes (): Promise<Hero[]> {
return this.http.get(this.heroesUrl) return this.http.get(this.heroesUrl)

View File

@ -20,11 +20,10 @@ import { WikipediaService } from './wikipedia.service';
providers: [JSONP_PROVIDERS, WikipediaService] providers: [JSONP_PROVIDERS, WikipediaService]
}) })
export class WikiComponent { export class WikiComponent {
items: Observable<string[]>;
constructor (private wikipediaService: WikipediaService) {} constructor (private wikipediaService: WikipediaService) {}
items: Observable<string[]>;
search (term: string) { search (term: string) {
this.items = this.wikipediaService.search(term); this.items = this.wikipediaService.search(term);
} }

View File

@ -14,7 +14,7 @@ export class WikipediaService {
// #docregion query-string // #docregion query-string
let queryString = let queryString =
`?search=${term}&action=opensearch&format=json&callback=JSONP_CALLBACK` `?search=${term}&action=opensearch&format=json&callback=JSONP_CALLBACK`;
return this.jsonp return this.jsonp
.get(wikiUrl + queryString) .get(wikiUrl + queryString)

View File

@ -57,9 +57,9 @@ describe('Structural Directives', function () {
it('should be able to use *ngIf ', function () { it('should be able to use *ngIf ', function () {
let setConditionButtonEle = element.all(by.css('button')).get(0); let setConditionButtonEle = element.all(by.css('button')).get(0);
let displayEles = element.all(by.cssContainingText('p', 'Our heroes are true!')); let displayEles = element.all(by.cssContainingText('p', 'Our heroes are true!'));
expect(displayEles.count()).toBe(2, "should be displaying two ngIf elements"); expect(displayEles.count()).toBe(2, 'should be displaying two ngIf elements');
setConditionButtonEle.click().then(function() { setConditionButtonEle.click().then(function() {
expect(displayEles.count()).toBe(0, "should nog longer be displaying ngIf elements"); expect(displayEles.count()).toBe(0, 'should nog longer be displaying ngIf elements');
}); });
}); });
}); });

View File

@ -1,5 +1,5 @@
// #docregion // #docregion
import { Component, Input, Output } from '@angular/core'; import { Component, Input, OnDestroy, OnInit } from '@angular/core';
let nextId = 1; let nextId = 1;
@ -7,7 +7,7 @@ let nextId = 1;
selector: 'heavy-loader', selector: 'heavy-loader',
template: '<span>heavy loader #{{id}} on duty!</span>' template: '<span>heavy loader #{{id}} on duty!</span>'
}) })
export class HeavyLoaderComponent { export class HeavyLoaderComponent implements OnDestroy, OnInit {
id = nextId++; id = nextId++;
@Input() logs: string[]; @Input() logs: string[];

View File

@ -1,6 +1,6 @@
// #docplaster // #docplaster
// #docregion // #docregion
import { Component, Input, Output } from '@angular/core'; import { Component } from '@angular/core';
import { UnlessDirective } from './unless.directive'; import { UnlessDirective } from './unless.directive';
import { HeavyLoaderComponent } from './heavy-loader.component'; import { HeavyLoaderComponent } from './heavy-loader.component';

View File

@ -1,5 +1,5 @@
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { HeroArena, HeroService, Hero } from './heroes'; import { HeroArena, HeroService, Hero } from './heroes';
@ -8,7 +8,7 @@ import { HeroArena, HeroService, Hero } from './heroes';
template: '<pre>{{heroes | json}}</pre>', template: '<pre>{{heroes | json}}</pre>',
providers: [HeroArena, HeroService] providers: [HeroArena, HeroService]
}) })
export class AppComponent { export class AppComponent implements OnInit {
heroes: Hero[] = []; heroes: Hero[] = [];
constructor(private heroArena: HeroArena) { } constructor(private heroArena: HeroArena) { }

View File

@ -6,6 +6,6 @@ import { Directive, ElementRef } from '@angular/core';
@Directive({selector: 'select'}) @Directive({selector: 'select'})
export class DecoratorDirective { export class DecoratorDirective {
constructor(el: ElementRef) { constructor(el: ElementRef) {
console.log(el) console.log(el);
} }
} }

View File

@ -28,6 +28,12 @@ let nextHeroDetailId = 1;
}) })
// #enddocregion input-output-2 // #enddocregion input-output-2
export class HeroDetailComponent { export class HeroDetailComponent {
hero: Hero = new Hero('', 'Zzzzzzzz'); // default sleeping hero
// heroImageUrl = 'http://www.wpclipart.com/cartoon/people/hero/hero_silhoutte_T.png';
// Public Domain terms of use: http://www.wpclipart.com/terms.html
heroImageUrl = 'images/hero.png';
lineThrough = '';
@Input() prefix = '';
// #docregion deleteRequest // #docregion deleteRequest
// This component make a request but it can't actually delete a hero. // This component make a request but it can't actually delete a hero.
@ -40,13 +46,6 @@ export class HeroDetailComponent {
// #docregion deleteRequest // #docregion deleteRequest
} }
// #enddocregion deleteRequest // #enddocregion deleteRequest
hero: Hero = new Hero('','Zzzzzzzz'); // default sleeping hero
// heroImageUrl = 'http://www.wpclipart.com/cartoon/people/hero/hero_silhoutte_T.png';
// Public Domain terms of use: http://www.wpclipart.com/terms.html
heroImageUrl = 'images/hero.png';
lineThrough = '';
@Input() prefix = '';
} }
@Component({ @Component({

View File

@ -1,23 +1,4 @@
export class Hero { export class Hero {
public id:number
constructor(
public firstName:string,
public lastName?:string,
public birthdate?:Date,
public url?:string,
public rate:number = 100,
id?:number) {
this.id = id != null ? id : Hero.nextId++;
}
static clone({firstName, lastName, birthdate, url, rate, id} : Hero){
return new Hero (firstName, lastName, birthdate, url, rate, id );
}
get fullName() {return `${this.firstName} ${this.lastName}`;}
static nextId = 1; static nextId = 1;
static MockHeroes = [ static MockHeroes = [
@ -33,4 +14,23 @@ export class Hero {
new Hero('Miny', 'Toe'), new Hero('Miny', 'Toe'),
new Hero('Moe', 'Toe') new Hero('Moe', 'Toe')
]; ];
public id: number;
static clone({firstName, lastName, birthdate, url, rate, id}: Hero) {
return new Hero(firstName, lastName, birthdate, url, rate, id);
}
constructor(
public firstName: string,
public lastName?: string,
public birthdate?: Date,
public url?: string,
public rate = 100,
id?: number) {
this.id = id != null ? id : Hero.nextId++;
}
get fullName() { return `${this.firstName} ${this.lastName}`; }
} }

View File

@ -7,6 +7,8 @@ export class MyClickDirective {
@Output('myClick') clicks = new EventEmitter<string>(); // @Output(alias) propertyName = ... @Output('myClick') clicks = new EventEmitter<string>(); // @Output(alias) propertyName = ...
// #enddocregion my-click-output-1 // #enddocregion my-click-output-1
toggle = false;
constructor(el: ElementRef) { constructor(el: ElementRef) {
el.nativeElement el.nativeElement
.addEventListener('click', (event: Event) => { .addEventListener('click', (event: Event) => {
@ -14,7 +16,6 @@ export class MyClickDirective {
this.clicks.emit(this.toggle ? 'Click!' : ''); this.clicks.emit(this.toggle ? 'Click!' : '');
}); });
} }
toggle = false;
} }
// #docregion my-click-output-2 // #docregion my-click-output-2
@ -27,6 +28,7 @@ export class MyClickDirective {
// #enddocregion my-click-output-2 // #enddocregion my-click-output-2
export class MyClickDirective2 { export class MyClickDirective2 {
clicks = new EventEmitter<string>(); clicks = new EventEmitter<string>();
toggle = false;
constructor(el: ElementRef) { constructor(el: ElementRef) {
el.nativeElement el.nativeElement
@ -35,5 +37,4 @@ export class MyClickDirective2 {
this.clicks.emit(this.toggle ? 'Click2!' : ''); this.clicks.emit(this.toggle ? 'Click2!' : '');
}); });
} }
toggle = false;
} }

View File

@ -1,5 +1,5 @@
// Based on https://github.com/angular/angular/blob/master/modules/angular2/test/testing/testing_public_spec.ts // Based on https://github.com/angular/angular/blob/master/modules/angular2/test/testing/testing_public_spec.ts
/* tslint:disable:no-unused-variable */ /* tslint:disable */
import { import {
BadTemplateUrl, ButtonComp, BadTemplateUrl, ButtonComp,
ChildChildComp, ChildComp, ChildWithChildComp, ChildChildComp, ChildComp, ChildWithChildComp,

View File

@ -1,5 +1,5 @@
// Based on https://github.com/angular/angular/blob/master/modules/angular2/test/testing/testing_public_spec.ts // Based on https://github.com/angular/angular/blob/master/modules/angular2/test/testing/testing_public_spec.ts
/* tslint:disable:forin */ /* tslint:disable */
import { Component, EventEmitter, Injectable, Input, Output, Optional, import { Component, EventEmitter, Injectable, Input, Output, Optional,
OnInit, OnChanges, OnDestroy, SimpleChange } from '@angular/core'; OnInit, OnChanges, OnDestroy, SimpleChange } from '@angular/core';

View File

@ -1,3 +1,4 @@
/* tslint:disable */
// #docplaster // #docplaster
// #docregion // #docregion
// #docregion v2 // #docregion v2

View File

@ -8,8 +8,10 @@ import {Observable} from 'rxjs/Observable';
@Injectable() @Injectable()
export class HeroService { export class HeroService {
constructor (private http: Http) {}
private _heroesUrl = 'app/heroes'; // URL to web api private _heroesUrl = 'app/heroes'; // URL to web api
constructor (private http: Http) {}
getHeroes (): Observable<Hero[]> { getHeroes (): Observable<Hero[]> {
return this.http.get(this._heroesUrl) return this.http.get(this._heroesUrl)
.map(this.extractData) .map(this.extractData)

View File

@ -1,3 +1,4 @@
/* tslint:disable */
export * from '@angular/router-deprecated'; export * from '@angular/router-deprecated';
import { Directive, DynamicComponentLoader, ViewContainerRef, import { Directive, DynamicComponentLoader, ViewContainerRef,

View File

@ -25,7 +25,7 @@ template: '''
<div><label>id: </label>{{hero.id}}</div> <div><label>id: </label>{{hero.id}}</div>
<div> <div>
<label>name: </label> <label>name: </label>
<div><input value="{{hero.name}}" placeholder="name"></div> <input value="{{hero.name}}" placeholder="name">
</div>''' </div>'''
// #enddocregion editing-Hero // #enddocregion editing-Hero
@ -35,7 +35,3 @@ class AppComponent {
Hero hero = 'Windstorm'; Hero hero = 'Windstorm';
} }
// #enddocregion app-component-1 // #enddocregion app-component-1
// #docregion hero-property-1
Hero hero = new Hero(1, 'Windstorm');
// #enddocregion hero-property-1

View File

@ -18,11 +18,13 @@ class Hero {
<div><label>id: </label>{{hero.id}}</div> <div><label>id: </label>{{hero.id}}</div>
<div> <div>
<label>name: </label> <label>name: </label>
<div><input [(ngModel)]="hero.name" placeholder="name"></div> <input [(ngModel)]="hero.name" placeholder="name">
</div>''' </div>'''
) )
class AppComponent { class AppComponent {
String title = 'Tour of Heroes'; String title = 'Tour of Heroes';
// #docregion hero-property-1
Hero hero = new Hero(1, 'Windstorm'); Hero hero = new Hero(1, 'Windstorm');
// #enddocregion hero-property-1
} }
// #enddocregion pt1 // #enddocregion pt1

View File

@ -3,7 +3,7 @@ import 'package:angular2/platform/browser.dart';
import 'package:angular2_tour_of_heroes/app_component.dart'; import 'package:angular2_tour_of_heroes/app_component.dart';
main() { void main() {
bootstrap(AppComponent); bootstrap(AppComponent);
} }
// #enddocregion pt1 // #enddocregion pt1

View File

@ -93,17 +93,17 @@ export class AppComponent {
// #enddocregion pt2 // #enddocregion pt2
// #docregion hero-array // #docregion hero-array
var HEROES: Hero[] = [ const HEROES: Hero[] = [
{ "id": 11, "name": "Mr. Nice" }, { id: 11, name: 'Mr. Nice' },
{ "id": 12, "name": "Narco" }, { id: 12, name: 'Narco' },
{ "id": 13, "name": "Bombasto" }, { id: 13, name: 'Bombasto' },
{ "id": 14, "name": "Celeritas" }, { id: 14, name: 'Celeritas' },
{ "id": 15, "name": "Magneta" }, { id: 15, name: 'Magneta' },
{ "id": 16, "name": "RubberMan" }, { id: 16, name: 'RubberMan' },
{ "id": 17, "name": "Dynama" }, { id: 17, name: 'Dynama' },
{ "id": 18, "name": "Dr IQ" }, { id: 18, name: 'Dr IQ' },
{ "id": 19, "name": "Magma" }, { id: 19, name: 'Magma' },
{ "id": 20, "name": "Tornado" } { id: 20, name: 'Tornado' }
]; ];
// #enddocregion hero-array // #enddocregion hero-array

View File

@ -85,15 +85,15 @@ export class AppComponent {
onSelect(hero: Hero) { this.selectedHero = hero; } onSelect(hero: Hero) { this.selectedHero = hero; }
} }
var HEROES: Hero[] = [ const HEROES: Hero[] = [
{ "id": 11, "name": "Mr. Nice" }, { id: 11, name: 'Mr. Nice' },
{ "id": 12, "name": "Narco" }, { id: 12, name: 'Narco' },
{ "id": 13, "name": "Bombasto" }, { id: 13, name: 'Bombasto' },
{ "id": 14, "name": "Celeritas" }, { id: 14, name: 'Celeritas' },
{ "id": 15, "name": "Magneta" }, { id: 15, name: 'Magneta' },
{ "id": 16, "name": "RubberMan" }, { id: 16, name: 'RubberMan' },
{ "id": 17, "name": "Dynama" }, { id: 17, name: 'Dynama' },
{ "id": 18, "name": "Dr IQ" }, { id: 18, name: 'Dr IQ' },
{ "id": 19, "name": "Magma" }, { id: 19, name: 'Magma' },
{ "id": 20, "name": "Tornado" } { id: 20, name: 'Tornado' }
]; ];

View File

@ -19,19 +19,19 @@ describe('Tutorial', function () {
allHeroes: element.all(by.css('my-app my-heroes li')), allHeroes: element.all(by.css('my-app my-heroes li')),
heroDetail: element(by.css('my-app my-hero-detail')) heroDetail: element(by.css('my-app my-hero-detail'))
} };
} }
it('should be able to see the start screen', function () { it('should be able to see the start screen', function () {
let page = getPageStruct(); let page = getPageStruct();
expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices'); expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices');
expect(page.myDashboardHref.getText()).toEqual("Dashboard"); expect(page.myDashboardHref.getText()).toEqual('Dashboard');
expect(page.myHeroesHref.getText()).toEqual("Heroes"); expect(page.myHeroesHref.getText()).toEqual('Heroes');
}); });
it('should be able to see dashboard choices', function () { it('should be able to see dashboard choices', function () {
let page = getPageStruct(); let page = getPageStruct();
expect(page.topHeroes.count()).toBe(4, "should be 4 dashboard hero choices"); expect(page.topHeroes.count()).toBe(4, 'should be 4 dashboard hero choices');
}); });
it('should be able to toggle the views', function () { it('should be able to toggle the views', function () {
@ -40,7 +40,7 @@ describe('Tutorial', function () {
expect(page.myDashboardParent.element(by.css('h3')).getText()).toEqual('Top Heroes'); expect(page.myDashboardParent.element(by.css('h3')).getText()).toEqual('Top Heroes');
page.myHeroesHref.click().then(function() { page.myHeroesHref.click().then(function() {
expect(page.myDashboardParent.isPresent()).toBe(false, 'should no longer see dashboard element'); expect(page.myDashboardParent.isPresent()).toBe(false, 'should no longer see dashboard element');
expect(page.allHeroes.count()).toBeGreaterThan(4, "should be more than 4 heroes shown"); expect(page.allHeroes.count()).toBeGreaterThan(4, 'should be more than 4 heroes shown');
return page.myDashboardHref.click(); return page.myDashboardHref.click();
}).then(function() { }).then(function() {
expect(page.myDashboardParent.isPresent()).toBe(true, 'should once again see the dashboard element'); expect(page.myDashboardParent.isPresent()).toBe(true, 'should once again see the dashboard element');

View File

@ -9,7 +9,7 @@ upgradeAdapter.addProvider(Heroes);
angular.module('heroApp', []) angular.module('heroApp', [])
.factory('heroes', upgradeAdapter.downgradeNg2Provider(Heroes)) .factory('heroes', upgradeAdapter.downgradeNg2Provider(Heroes))
.component('heroDetail', heroDetailComponent) .component('heroDetail', heroDetailComponent);
// #enddocregion register // #enddocregion register
upgradeAdapter.bootstrap( upgradeAdapter.bootstrap(

View File

@ -7,7 +7,7 @@ declare var angular:any;
angular.module('heroApp', []) angular.module('heroApp', [])
.directive('myContainer', upgradeAdapter.downgradeNg2Component(ContainerComponent)) .directive('myContainer', upgradeAdapter.downgradeNg2Component(ContainerComponent))
.component('heroDetail', heroDetailComponent) .component('heroDetail', heroDetailComponent);
upgradeAdapter.bootstrap( upgradeAdapter.bootstrap(
document.querySelector('hero-app'), document.querySelector('hero-app'),

View File

@ -11,7 +11,7 @@ import {Hero} from '../hero';
` `
}) })
export class HeroDetailComponent { export class HeroDetailComponent {
@Input() hero:Hero @Input() hero: Hero;
@Output() deleted = new EventEmitter<Hero>(); @Output() deleted = new EventEmitter<Hero>();
onDelete() { onDelete() {
this.deleted.emit(this.hero); this.deleted.emit(this.hero);

View File

@ -5,7 +5,7 @@ export class MainController {
heroes = [ heroes = [
new Hero(2, 'Superman'), new Hero(2, 'Superman'),
new Hero(3, 'Spiderman') new Hero(3, 'Spiderman')
] ];
onDelete(hero: Hero) { onDelete(hero: Hero) {
hero.name = 'Ex-' + hero.name; hero.name = 'Ex-' + hero.name;
} }

View File

@ -18,5 +18,5 @@ export function heroDetailDirective() {
}; };
}, },
controllerAs: 'ctrl' controllerAs: 'ctrl'
} };
} }

View File

@ -9,7 +9,7 @@ angular.
}; };
function animateIn(element: JQuery, className: string, done: () => void) { function animateIn(element: JQuery, className: string, done: () => void) {
if (className !== 'selected') return; if (className !== 'selected') { return; }
element.css({ element.css({
display: 'block', display: 'block',
@ -21,12 +21,12 @@ angular.
}, done); }, done);
return function animateInEnd(wasCanceled: boolean) { return function animateInEnd(wasCanceled: boolean) {
if (wasCanceled) element.stop(); if (wasCanceled) { element.stop(); }
}; };
} }
function animateOut(element: JQuery, className: string, done: () => void) { function animateOut(element: JQuery, className: string, done: () => void) {
if (className !== 'selected') return; if (className !== 'selected') { return; }
element.css({ element.css({
position: 'absolute', position: 'absolute',
@ -37,7 +37,7 @@ angular.
}, done); }, done);
return function animateOutEnd(wasCanceled: boolean) { return function animateOutEnd(wasCanceled: boolean) {
if (wasCanceled) element.stop(); if (wasCanceled) { element.stop(); }
}; };
} }
}); });

View File

@ -32,7 +32,7 @@ describe('Phone', () => {
}); });
it('should fetch the phones data from `/phones/phones.json`', () => { it('should fetch the phones data from `/phones/phones.json`', () => {
var phones = Phone.query(); let phones = Phone.query();
expect(phones).toEqual([]); expect(phones).toEqual([]);

View File

@ -6,7 +6,7 @@ describe('phoneDetail', () => {
// Test the controller // Test the controller
describe('PhoneDetailController', () => { describe('PhoneDetailController', () => {
let $httpBackend: angular.IHttpBackendService let $httpBackend: angular.IHttpBackendService;
let ctrl: any; let ctrl: any;
let xyzPhoneData = { let xyzPhoneData = {
name: 'phone xyz', name: 'phone xyz',

View File

@ -9,7 +9,7 @@ angular.
}; };
function animateIn(element: JQuery, className: string, done: () => void) { function animateIn(element: JQuery, className: string, done: () => void) {
if (className !== 'selected') return; if (className !== 'selected') { return; }
element.css({ element.css({
display: 'block', display: 'block',
@ -21,12 +21,12 @@ angular.
}, done); }, done);
return function animateInEnd(wasCanceled: boolean) { return function animateInEnd(wasCanceled: boolean) {
if (wasCanceled) element.stop(); if (wasCanceled) { element.stop(); }
}; };
} }
function animateOut(element: JQuery, className: string, done: () => void) { function animateOut(element: JQuery, className: string, done: () => void) {
if (className !== 'selected') return; if (className !== 'selected') { return; }
element.css({ element.css({
position: 'absolute', position: 'absolute',
@ -37,7 +37,7 @@ angular.
}, done); }, done);
return function animateOutEnd(wasCanceled: boolean) { return function animateOutEnd(wasCanceled: boolean) {
if (wasCanceled) element.stop(); if (wasCanceled) { element.stop(); }
}; };
} }
}); });

View File

@ -22,7 +22,7 @@ function xyzPhoneData():PhoneData {
name: 'phone xyz', name: 'phone xyz',
snippet: '', snippet: '',
images: ['image/url1.png', 'image/url2.png'] images: ['image/url1.png', 'image/url2.png']
} };
} }
class MockPhone extends Phone { class MockPhone extends Phone {

View File

@ -24,7 +24,7 @@ class MockPhone extends Phone {
{name: 'Nexus S', snippet: '', images: []}, {name: 'Nexus S', snippet: '', images: []},
{name: 'Motorola DROID', snippet: '', images: []} {name: 'Motorola DROID', snippet: '', images: []}
] ]
) );
} }
} }

View File

@ -26,7 +26,7 @@ function xyzPhoneData():PhoneData {
name: 'phone xyz', name: 'phone xyz',
snippet: '', snippet: '',
images: ['image/url1.png', 'image/url2.png'] images: ['image/url1.png', 'image/url2.png']
} };
} }
class MockPhone extends Phone { class MockPhone extends Phone {

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