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:
		
						commit
						f2dbdb3163
					
				
							
								
								
									
										10
									
								
								gulpfile.js
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								gulpfile.js
									
									
									
									
									
								
							| @ -636,7 +636,15 @@ gulp.task('_zip-examples', function() { | ||||
| // Linting
 | ||||
| 
 | ||||
| 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({ | ||||
|       rulesDirectory: ['node_modules/codelyzer'], | ||||
|       configuration: require('./tslint.json') | ||||
|  | ||||
| @ -31,7 +31,7 @@ | ||||
|     "browser-sync": "^2.9.3", | ||||
|     "canonical-path": "0.0.2", | ||||
|     "cross-spawn": "^4.0.0", | ||||
|     "codelyzer": "0.0.20", | ||||
|     "codelyzer": "0.0.22", | ||||
|     "del": "^2.2.0", | ||||
|     "dgeni": "^0.4.0", | ||||
|     "dgeni-packages": "^0.13.0", | ||||
|  | ||||
| @ -13,7 +13,7 @@ const HEROES = [ | ||||
| export class BackendService { | ||||
|   constructor(private logger: Logger) {} | ||||
| 
 | ||||
|   getAll(type:Type) : PromiseLike<any[]>{ | ||||
|   getAll(type: Type): PromiseLike<any[]> { | ||||
|     if (type === Hero) { | ||||
|       // TODO get from the database
 | ||||
|       return Promise.resolve<Hero[]>(HEROES); | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| import { Component, Input} from '@angular/core'; | ||||
| import { Component, Input } from '@angular/core'; | ||||
| 
 | ||||
| import { Hero } from './hero'; | ||||
| 
 | ||||
|  | ||||
| @ -35,7 +35,7 @@ export class SalesTaxComponent { | ||||
|   constructor(private salesTaxService: SalesTaxService) { } | ||||
| // #enddocregion ctor
 | ||||
| 
 | ||||
|   getTax(value:string | number){ | ||||
|   getTax(value: string | number) { | ||||
|     return this.salesTaxService.getVAT(value); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| // #docregion
 | ||||
| import { Inject, Injectable }     from '@angular/core'; | ||||
| import { Inject, Injectable } from '@angular/core'; | ||||
| 
 | ||||
| import { TaxRateService } from './tax-rate.service'; | ||||
| 
 | ||||
| @ -7,9 +7,9 @@ import { TaxRateService } from './tax-rate.service'; | ||||
| @Injectable() | ||||
| export class SalesTaxService { | ||||
|   constructor(private rateService: TaxRateService) { } | ||||
|   getVAT(value:string | number){ | ||||
|     let amount:number; | ||||
|     if (typeof value === "string"){ | ||||
|   getVAT(value: string | number) { | ||||
|     let amount: number; | ||||
|     if (typeof value === 'string') { | ||||
|       amount = parseFloat(value); | ||||
|     } else { | ||||
|       amount = value; | ||||
|  | ||||
| @ -4,6 +4,6 @@ import { Injectable } from '@angular/core'; | ||||
| // #docregion class
 | ||||
| @Injectable() | ||||
| export class TaxRateService { | ||||
|   getRate(rateName:string){return 0.10;} // always 10% everywhere
 | ||||
|   getRate(rateName: string) {return 0.10; } // always 10% everywhere
 | ||||
| } | ||||
| // #enddocregion class
 | ||||
|  | ||||
| @ -11,4 +11,4 @@ import { HighlightDirective } from './highlight.directive'; | ||||
| 
 | ||||
| export class AppComponent { } | ||||
| 
 | ||||
| // #enddocregion
 | ||||
| // #enddocregion
 | ||||
|  | ||||
| @ -14,12 +14,12 @@ import { Directive, ElementRef, Input } from '@angular/core'; | ||||
| export class HighlightDirective { | ||||
| 
 | ||||
|   // #docregion ctor
 | ||||
|   private el:HTMLElement; | ||||
|   private el: HTMLElement; | ||||
|   constructor(el: ElementRef) { this.el = el.nativeElement; } | ||||
|   // #enddocregion ctor
 | ||||
| 
 | ||||
|   // #docregion mouse-methods
 | ||||
|   onMouseEnter() { this.highlight("yellow"); } | ||||
|   onMouseEnter() { this.highlight('yellow'); } | ||||
|   onMouseLeave() { this.highlight(null); } | ||||
| 
 | ||||
|   private highlight(color: string) { | ||||
|  | ||||
| @ -13,12 +13,12 @@ import { Directive, ElementRef, Input } from '@angular/core'; | ||||
| export class HighlightDirective { | ||||
|   private _defaultColor = 'red'; | ||||
|   private el: HTMLElement; | ||||
|      | ||||
| 
 | ||||
|   constructor(el: ElementRef) { this.el = el.nativeElement; } | ||||
|   // #enddocregion class-1
 | ||||
| 
 | ||||
|   // #docregion defaultColor
 | ||||
|   @Input() set defaultColor(colorName:string){ | ||||
|   @Input() set defaultColor(colorName: string){ | ||||
|     this._defaultColor = colorName || this._defaultColor; | ||||
|   } | ||||
|   // #enddocregion defaultColor
 | ||||
| @ -33,7 +33,7 @@ export class HighlightDirective { | ||||
|   // #enddocregion mouse-enter
 | ||||
|   onMouseLeave() { this.highlight(null); } | ||||
| 
 | ||||
|   private highlight(color:string) { | ||||
|   private highlight(color: string) { | ||||
|     this.el.style.backgroundColor = color; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -85,7 +85,7 @@ describe('Angular 1 to 2 Quick Reference Tests', function () { | ||||
| 
 | ||||
|     posterButton.click().then(function () { | ||||
|       testImagesAreDisplayed(isDisplayed); | ||||
|     }) | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   function getMovieRows() { | ||||
| @ -107,7 +107,7 @@ describe('Angular 1 to 2 Quick Reference Tests', function () { | ||||
|         } else { | ||||
|           expect(favoriteHeroLabel.isDisplayed()).toBe(false); | ||||
|         } | ||||
|       }) | ||||
|     }) | ||||
|       }); | ||||
|     }); | ||||
|   } | ||||
| }); | ||||
|  | ||||
| @ -11,7 +11,7 @@ import { StringSafeDatePipe } from './date.pipe'; | ||||
| // #docregion component
 | ||||
| @Component({ | ||||
|   selector: 'movie-list', | ||||
|   templateUrl:'app/movie-list.component.html', | ||||
|   templateUrl: 'app/movie-list.component.html', | ||||
| // #enddocregion component
 | ||||
| // #docregion style-url
 | ||||
|   styleUrls: ['app/movie-list.component.css'], | ||||
|  | ||||
| @ -19,8 +19,8 @@ describe('Component Communication Cookbook Tests', function () { | ||||
|       for (let i = 0; i < _heroNames.length; i++) { | ||||
|         let childTitle = heroes.get(i).element(by.tagName('h3')).getText(); | ||||
|         let childDetail = heroes.get(i).element(by.tagName('p')).getText(); | ||||
|         expect(childTitle).toEqual(_heroNames[i] + ' says:') | ||||
|         expect(childDetail).toContain(_masterName) | ||||
|         expect(childTitle).toEqual(_heroNames[i] + ' says:'); | ||||
|         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 displayName = hero.element(by.tagName('h3')).getText(); | ||||
|       expect(displayName).toEqual(_nonEmptyName) | ||||
|       expect(displayName).toEqual(_nonEmptyName); | ||||
|     }); | ||||
| 
 | ||||
|     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 displayName = hero.element(by.tagName('h3')).getText(); | ||||
|       expect(displayName).toEqual(_defaultName) | ||||
|       expect(displayName).toEqual(_defaultName); | ||||
|     }); | ||||
|     // ...
 | ||||
|     // #enddocregion parent-to-child-setter
 | ||||
| @ -82,7 +82,7 @@ describe('Component Communication Cookbook Tests', function () { | ||||
|           expect(actual.label).toBe(labelAfter2Minor); | ||||
|           expect(actual.count).toBe(3); | ||||
|           expect(actual.logs.get(2).getText()).toBe(logAfter2Minor); | ||||
|         }) | ||||
|         }); | ||||
|       }); | ||||
|     }); | ||||
| 
 | ||||
| @ -150,13 +150,15 @@ describe('Component Communication Cookbook Tests', function () { | ||||
|     // ...
 | ||||
|     // #enddocregion child-to-parent
 | ||||
|   }); | ||||
|    | ||||
|   describe('Parent calls child via local var', function() { | ||||
|     countDownTimerTests('countdown-parent-lv') | ||||
|   });     | ||||
|    | ||||
|   describe('Parent calls ViewChild', function() { | ||||
|     countDownTimerTests('countdown-parent-vc') | ||||
| 
 | ||||
|   // Can't run timer tests in protractor because
 | ||||
|   // interaction w/ zones causes all tests to freeze & timeout.
 | ||||
|   xdescribe('Parent calls child via local var', function() { | ||||
|     countDownTimerTests('countdown-parent-lv'); | ||||
|   }); | ||||
| 
 | ||||
|   xdescribe('Parent calls ViewChild', function() { | ||||
|     countDownTimerTests('countdown-parent-vc'); | ||||
|   }); | ||||
| 
 | ||||
|   function countDownTimerTests(parentTag: string) { | ||||
| @ -180,7 +182,7 @@ describe('Component Communication Cookbook Tests', function () { | ||||
|       }); | ||||
|     }); | ||||
|     // ...
 | ||||
|     // #enddocregion countdown-timer-tests    
 | ||||
|     // #enddocregion countdown-timer-tests
 | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -16,9 +16,20 @@ import { MissionControlComponent } from './missioncontrol.component'; | ||||
|     NameParentComponent, | ||||
|     VersionParentComponent, | ||||
|     VoteTakerComponent, | ||||
|     CountdownLocalVarParentComponent, | ||||
|     CountdownViewChildParentComponent, | ||||
|     MissionControlComponent | ||||
|   ] | ||||
|     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 { } | ||||
|  | ||||
| @ -17,12 +17,12 @@ import { Subscription }   from 'rxjs/Subscription'; | ||||
|     </p> | ||||
|   ` | ||||
| }) | ||||
| export class AstronautComponent implements OnDestroy{ | ||||
| export class AstronautComponent implements OnDestroy { | ||||
|   @Input() astronaut: string; | ||||
|   mission = "<no mission announced>"; | ||||
|   mission = '<no mission announced>'; | ||||
|   confirmed = false; | ||||
|   announced = false; | ||||
|   subscription:Subscription; | ||||
|   subscription: Subscription; | ||||
| 
 | ||||
|   constructor(private missionService: MissionService) { | ||||
|     this.subscription = missionService.missionAnnounced$.subscribe( | ||||
| @ -30,7 +30,7 @@ export class AstronautComponent implements OnDestroy{ | ||||
|         this.mission = mission; | ||||
|         this.announced = true; | ||||
|         this.confirmed = false; | ||||
|     }) | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   confirm() { | ||||
| @ -38,9 +38,9 @@ export class AstronautComponent implements OnDestroy{ | ||||
|     this.missionService.confirmMission(this.astronaut); | ||||
|   } | ||||
| 
 | ||||
|   ngOnDestroy(){ | ||||
|   ngOnDestroy() { | ||||
|     // prevent memory leak when component destroyed
 | ||||
|     this.subscription.unsubscribe(); | ||||
|   } | ||||
| } | ||||
| // #enddocregion
 | ||||
| // #enddocregion
 | ||||
|  | ||||
| @ -11,7 +11,7 @@ import { CountdownTimerComponent }  from './countdown-timer.component'; | ||||
| //// Local variable, #timer, version
 | ||||
| // #docregion lv
 | ||||
| @Component({ | ||||
|   selector:'countdown-parent-lv', | ||||
|   selector: 'countdown-parent-lv', | ||||
|   template: ` | ||||
|   <h3>Countdown to Liftoff (via local variable)</h3> | ||||
|   <button (click)="timer.start()">Start</button> | ||||
| @ -28,7 +28,7 @@ export class CountdownLocalVarParentComponent { } | ||||
| //// View Child version
 | ||||
| // #docregion vc
 | ||||
| @Component({ | ||||
|   selector:'countdown-parent-vc', | ||||
|   selector: 'countdown-parent-vc', | ||||
|   template: ` | ||||
|   <h3>Countdown to Liftoff (via ViewChild)</h3> | ||||
|   <button (click)="start()">Start</button> | ||||
| @ -42,7 +42,7 @@ export class CountdownLocalVarParentComponent { } | ||||
| export class CountdownViewChildParentComponent implements AfterViewInit { | ||||
| 
 | ||||
|   @ViewChild(CountdownTimerComponent) | ||||
|   private timerComponent:CountdownTimerComponent; | ||||
|   private timerComponent: CountdownTimerComponent; | ||||
| 
 | ||||
|   seconds() { return 0; } | ||||
| 
 | ||||
| @ -50,10 +50,10 @@ export class CountdownViewChildParentComponent implements AfterViewInit { | ||||
|     // Redefine `seconds()` to get from the `CountdownTimerComponent.seconds` ...
 | ||||
|     // but wait a tick first to avoid one-time devMode
 | ||||
|     // 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(); } | ||||
|   stop() { this.timerComponent.stop(); } | ||||
| } | ||||
| // #enddocregion vc
 | ||||
|  | ||||
| @ -11,7 +11,7 @@ export class CountdownTimerComponent implements OnInit, OnDestroy { | ||||
|   message = ''; | ||||
|   seconds = 11; | ||||
| 
 | ||||
|   clearTimer() {clearInterval(this.intervalId);} | ||||
|   clearTimer() { clearInterval(this.intervalId); } | ||||
| 
 | ||||
|   ngOnInit()    { this.start(); } | ||||
|   ngOnDestroy() { this.clearTimer(); } | ||||
|  | ||||
| @ -6,4 +6,4 @@ export const HEROES = [ | ||||
|   {name: 'Mr. IQ'}, | ||||
|   {name: 'Magneta'}, | ||||
|   {name: 'Bombasto'} | ||||
| ]; | ||||
| ]; | ||||
|  | ||||
| @ -2,4 +2,4 @@ import { bootstrap }    from '@angular/platform-browser-dynamic'; | ||||
| 
 | ||||
| import { AppComponent } from './app.component'; | ||||
| 
 | ||||
| bootstrap(AppComponent); | ||||
| bootstrap(AppComponent); | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| // #docregion
 | ||||
| import { Injectable } from '@angular/core' | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { Subject }    from 'rxjs/Subject'; | ||||
| 
 | ||||
| @Injectable() | ||||
| @ -15,7 +15,7 @@ export class MissionService { | ||||
| 
 | ||||
|   // Service message commands
 | ||||
|   announceMission(mission: string) { | ||||
|     this.missionAnnouncedSource.next(mission) | ||||
|     this.missionAnnouncedSource.next(mission); | ||||
|   } | ||||
| 
 | ||||
|   confirmMission(astronaut: string) { | ||||
|  | ||||
| @ -21,7 +21,7 @@ import { MissionService }     from './mission.service'; | ||||
|   providers: [MissionService] | ||||
| }) | ||||
| export class MissionControlComponent { | ||||
|   astronauts = ['Lovell', 'Swigert', 'Haise'] | ||||
|   astronauts = ['Lovell', 'Swigert', 'Haise']; | ||||
|   history: string[] = []; | ||||
|   missions = ['Fly to the moon!', | ||||
|               'Fly to mars!', | ||||
| @ -32,7 +32,7 @@ export class MissionControlComponent { | ||||
|     missionService.missionConfirmed$.subscribe( | ||||
|       astronaut => { | ||||
|         this.history.push(`${astronaut} confirmed the mission`); | ||||
|       }) | ||||
|       }); | ||||
|   } | ||||
| 
 | ||||
|   announce() { | ||||
|  | ||||
| @ -17,7 +17,7 @@ export class VersionChildComponent implements OnChanges { | ||||
|   @Input() minor: number; | ||||
|   changeLog: string[] = []; | ||||
| 
 | ||||
|   ngOnChanges(changes: {[propKey:string]: SimpleChange}){ | ||||
|   ngOnChanges(changes: {[propKey: string]: SimpleChange}) { | ||||
|     let log: string[] = []; | ||||
|     for (let propName in changes) { | ||||
|       let changedProp = changes[propName]; | ||||
|  | ||||
| @ -14,9 +14,9 @@ export class VoterComponent { | ||||
|   @Output() onVoted = new EventEmitter<boolean>(); | ||||
|   voted = false; | ||||
| 
 | ||||
|   vote(agreed:boolean){ | ||||
|   vote(agreed: boolean) { | ||||
|     this.onVoted.emit(agreed); | ||||
|     this.voted = true; | ||||
|   } | ||||
| } | ||||
| // #enddocregion
 | ||||
| // #enddocregion
 | ||||
|  | ||||
| @ -18,7 +18,7 @@ import { VoterComponent } from './voter.component'; | ||||
| export class VoteTakerComponent { | ||||
|   agreed = 0; | ||||
|   disagreed = 0; | ||||
|   voters = ['Mr. IQ', 'Ms. Universe', 'Bombasto'] | ||||
|   voters = ['Mr. IQ', 'Ms. Universe', 'Bombasto']; | ||||
| 
 | ||||
|   onVoted(agreed: boolean) { | ||||
|     agreed ? this.agreed++ : this.disagreed++; | ||||
|  | ||||
| @ -12,7 +12,7 @@ describe('Cookbook: component-relative paths', function () { | ||||
|       title: element( by.tagName( 'h1' )), | ||||
|       absComp: element( by.css( 'absolute-path div' ) ), | ||||
|       relComp: element( by.css( 'relative-path div' ) ) | ||||
|     } | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   let page: Page; | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| // #docregion
 | ||||
| import { Component } from '@angular/core'; | ||||
| 
 | ||||
| import { SomeAbsoluteComponent, SomeRelativeComponent} from './some.component'; | ||||
| import { SomeAbsoluteComponent, SomeRelativeComponent } from './some.component'; | ||||
| 
 | ||||
| @Component({ | ||||
| selector: 'my-app', | ||||
|  | ||||
| @ -66,7 +66,7 @@ describe('Dependency Injection Cookbook', 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)'; | ||||
| 
 | ||||
|       expect(target.getCssValue('background-color')).not.toEqual(yellow); | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
| import { Component } from '@angular/core'; | ||||
| 
 | ||||
| import { HeroBiosComponent, | ||||
|          HeroBiosAndContactsComponent} from './hero-bios.component'; | ||||
|          HeroBiosAndContactsComponent } from './hero-bios.component'; | ||||
| import { HeroOfTheMonthComponent }     from './hero-of-the-month.component'; | ||||
| import { HeroesBaseComponent, | ||||
|          SortedHeroesComponent }       from './sorted-heroes.component'; | ||||
|  | ||||
| @ -6,9 +6,9 @@ import { HeroCacheService }         from './hero-cache.service'; | ||||
| 
 | ||||
| // #docregion component
 | ||||
| @Component({ | ||||
|   selector:'hero-bio', | ||||
|   selector: 'hero-bio', | ||||
|   // #docregion template
 | ||||
|   template:` | ||||
|   template: ` | ||||
|     <h4>{{hero.name}}</h4> | ||||
|     <ng-content></ng-content> | ||||
|     <textarea cols="25" [(ngModel)]="hero.description"></textarea>`,
 | ||||
| @ -18,9 +18,9 @@ import { HeroCacheService }         from './hero-cache.service'; | ||||
| 
 | ||||
| export class HeroBioComponent implements OnInit  { | ||||
| 
 | ||||
|   @Input() heroId:number; | ||||
|   @Input() heroId: number; | ||||
| 
 | ||||
|   constructor(private heroCache:HeroCacheService) { } | ||||
|   constructor(private heroCache: HeroCacheService) { } | ||||
| 
 | ||||
|   ngOnInit() { this.heroCache.fetchCachedHero(this.heroId); } | ||||
| 
 | ||||
|  | ||||
| @ -10,15 +10,15 @@ import { LoggerService }        from './logger.service'; | ||||
| //////// HeroBiosComponent ////
 | ||||
| // #docregion simple
 | ||||
| @Component({ | ||||
|   selector:'hero-bios', | ||||
|   template:` | ||||
|   selector: 'hero-bios', | ||||
|   template: ` | ||||
|     <hero-bio [heroId]="1"></hero-bio> | ||||
|     <hero-bio [heroId]="2"></hero-bio> | ||||
|     <hero-bio [heroId]="3"></hero-bio>`, | ||||
|   directives:[HeroBioComponent], | ||||
|   directives: [HeroBioComponent], | ||||
|   providers: [HeroService] | ||||
| }) | ||||
| export class HeroBiosComponent{ | ||||
| export class HeroBiosComponent { | ||||
| // #enddocregion simple
 | ||||
| // #docregion ctor
 | ||||
|   constructor(logger: LoggerService) { | ||||
| @ -32,21 +32,21 @@ export class HeroBiosComponent{ | ||||
| //////// HeroBiosAndContactsComponent ////
 | ||||
| // #docregion hero-bios-and-contacts
 | ||||
| @Component({ | ||||
|   selector:'hero-bios-and-contacts', | ||||
|   selector: 'hero-bios-and-contacts', | ||||
|   // #docregion template
 | ||||
|   template:` | ||||
|   template: ` | ||||
|     <hero-bio [heroId]="1"> <hero-contact></hero-contact> </hero-bio> | ||||
|     <hero-bio [heroId]="2"> <hero-contact></hero-contact> </hero-bio> | ||||
|     <hero-bio [heroId]="3"> <hero-contact></hero-contact> </hero-bio>`, | ||||
|   // #enddocregion template
 | ||||
|   directives:[HeroBioComponent, HeroContactComponent], | ||||
|   directives: [HeroBioComponent, HeroContactComponent], | ||||
|   // #docregion class-provider
 | ||||
|   providers: [HeroService] | ||||
|   // #enddocregion class-provider
 | ||||
| }) | ||||
| export class HeroBiosAndContactsComponent{ | ||||
| export class HeroBiosAndContactsComponent { | ||||
|   constructor(logger: LoggerService) { | ||||
|     logger.logInfo('Creating HeroBiosAndContactsComponent'); | ||||
|   } | ||||
| } | ||||
| // #enddocregion hero-bios-and-contacts
 | ||||
| // #enddocregion hero-bios-and-contacts
 | ||||
|  | ||||
| @ -7,14 +7,14 @@ import { HeroService } from './hero.service'; | ||||
| // #docregion service
 | ||||
| @Injectable() | ||||
| export class HeroCacheService { | ||||
|   hero:Hero; | ||||
|   constructor(private heroService:HeroService){} | ||||
|   hero: Hero; | ||||
|   constructor(private heroService: HeroService) {} | ||||
| 
 | ||||
|   fetchCachedHero(id:number){ | ||||
|   fetchCachedHero(id: number) { | ||||
|     if (!this.hero) { | ||||
|       this.hero = this.heroService.getHeroById(id); | ||||
|     } | ||||
|     return this.hero | ||||
|     return this.hero; | ||||
|   } | ||||
| } | ||||
| // #enddocregion service
 | ||||
|  | ||||
| @ -1,14 +1,14 @@ | ||||
| // #docplaster
 | ||||
| // #docregion
 | ||||
| import { Component, ElementRef, Host, Inject,  Optional } from '@angular/core'; | ||||
| import { Component, ElementRef, Host, Inject, Optional } from '@angular/core'; | ||||
| 
 | ||||
| import { HeroCacheService } from './hero-cache.service'; | ||||
| import { LoggerService }    from './logger.service'; | ||||
| 
 | ||||
| // #docregion component
 | ||||
| @Component({ | ||||
|   selector:'hero-contact', | ||||
|   template:` | ||||
|   selector: 'hero-contact', | ||||
|   template: ` | ||||
|   <div>Phone #: {{phoneNumber}} | ||||
|   <span *ngIf="hasLogger">!!!</span></div>` | ||||
| }) | ||||
|  | ||||
| @ -4,10 +4,10 @@ import { Hero } from './hero'; | ||||
| export class HeroData { | ||||
|   createDb() { | ||||
|     let heroes = [ | ||||
|       new Hero(1,"Windstorm"), | ||||
|       new Hero(2,"Bombasto"), | ||||
|       new Hero(3,"Magneta"), | ||||
|       new Hero(4,"Tornado") | ||||
|       new Hero(1, 'Windstorm'), | ||||
|       new Hero(2, 'Bombasto'), | ||||
|       new Hero(3, 'Magneta'), | ||||
|       new Hero(4, 'Tornado') | ||||
|     ]; | ||||
|     return {heroes}; | ||||
|   } | ||||
|  | ||||
| @ -5,18 +5,18 @@ import { Hero }       from './hero'; | ||||
| @Injectable() | ||||
| export class HeroService { | ||||
| 
 | ||||
|   //TODO move to database
 | ||||
|   private heroes:Array<Hero> = [ | ||||
|     new Hero(1, 'RubberMan','Hero of many talents', '123-456-7899'), | ||||
|     new Hero(2, 'Magma','Hero of all trades', '555-555-5555'), | ||||
|     new Hero(3, 'Mr. Nice','The name says it all','111-222-3333') | ||||
|   // TODO move to database
 | ||||
|   private heroes: Array<Hero> = [ | ||||
|     new Hero(1, 'RubberMan', 'Hero of many talents', '123-456-7899'), | ||||
|     new Hero(2, 'Magma', 'Hero of all trades', '555-555-5555'), | ||||
|     new Hero(3, 'Mr. Nice', 'The name says it all', '111-222-3333') | ||||
|  ]; | ||||
| 
 | ||||
|   getHeroById(id:number):Hero{ | ||||
|   getHeroById(id: number): Hero { | ||||
|     return this.heroes.filter(hero => hero.id === id)[0]; | ||||
|   } | ||||
| 
 | ||||
|   getAllHeroes():Array<Hero>{ | ||||
|   getAllHeroes(): Array<Hero> { | ||||
|     return this.heroes; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,9 +1,9 @@ | ||||
| // #docregion
 | ||||
| export class Hero{ | ||||
| export class Hero { | ||||
|   constructor( | ||||
|     public id: number, | ||||
|     public name:string, | ||||
|     public description?:string, | ||||
|     public phone?:string) { | ||||
|     public name: string, | ||||
|     public description?: string, | ||||
|     public phone?: string) { | ||||
|   } | ||||
| } | ||||
| } | ||||
|  | ||||
| @ -23,7 +23,7 @@ const provideParent = | ||||
| // #enddocregion provide-parent, provide-the-parent
 | ||||
| // #docregion provide-parent
 | ||||
|   (component: any, parentType?: any) => { | ||||
|     return { provide: parentType || Parent, useExisting: forwardRef(() => component) } | ||||
|     return { provide: parentType || Parent, useExisting: forwardRef(() => component) }; | ||||
|   }; | ||||
| // #enddocregion provide-parent
 | ||||
| 
 | ||||
| @ -31,7 +31,7 @@ const provideParent = | ||||
| const provideTheParent = | ||||
| // #docregion provide-the-parent
 | ||||
|   (component: any) => { | ||||
|     return { provide: Parent, useExisting: forwardRef(() => component) } | ||||
|     return { provide: Parent, useExisting: forwardRef(() => component) }; | ||||
|   }; | ||||
| // #enddocregion provide-the-parent
 | ||||
| 
 | ||||
|  | ||||
| @ -9,19 +9,19 @@ import { UserService }   from './user.service'; | ||||
| @Injectable() | ||||
| export class UserContextService { | ||||
| // #enddocregion injectables, injectable
 | ||||
|   name:string; | ||||
|   role:string; | ||||
|   loggedInSince:Date; | ||||
|   name: string; | ||||
|   role: string; | ||||
|   loggedInSince: Date; | ||||
| 
 | ||||
|   // #docregion ctor, injectables
 | ||||
|   constructor(private userService:UserService, private loggerService:LoggerService){ | ||||
|   constructor(private userService: UserService, private loggerService: LoggerService) { | ||||
|    // #enddocregion ctor, injectables
 | ||||
|     this.loggedInSince = new Date(); | ||||
|    // #docregion ctor, injectables
 | ||||
|   } | ||||
|   // #enddocregion ctor, injectables
 | ||||
| 
 | ||||
|   loadUser(userId:number){ | ||||
|   loadUser(userId: number) { | ||||
|     let user = this.userService.getUserById(userId); | ||||
|     this.name = user.name; | ||||
|     this.role = user.role; | ||||
|  | ||||
| @ -4,7 +4,7 @@ import { Injectable } from '@angular/core'; | ||||
| @Injectable() | ||||
| export class UserService { | ||||
| 
 | ||||
|   getUserById(userId:number):any{ | ||||
|     return {name:'Bombasto',role:'Admin'}; | ||||
|   getUserById(userId: number): any { | ||||
|     return {name: 'Bombasto', role: 'Admin'}; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -15,7 +15,7 @@ describe('Dynamic Form', function () { | ||||
|       emailElement.sendKeys(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); | ||||
|       saveButton.click().then(function(){ | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| // #docregion
 | ||||
| import { Component }       from '@angular/core' | ||||
| import { Component }       from '@angular/core'; | ||||
| 
 | ||||
| import { DynamicForm }     from './dynamic-form.component'; | ||||
| import { QuestionService } from './question.service'; | ||||
| @ -16,7 +16,7 @@ import { QuestionService } from './question.service'; | ||||
|   providers:  [QuestionService] | ||||
| }) | ||||
| export class AppComponent { | ||||
|   questions:any[] | ||||
|   questions: any[]; | ||||
| 
 | ||||
|   constructor(service: QuestionService) { | ||||
|     this.questions = service.getQuestions(); | ||||
|  | ||||
| @ -5,11 +5,11 @@ import { ControlGroup }     from '@angular/common'; | ||||
| import { QuestionBase }     from './question-base'; | ||||
| 
 | ||||
| @Component({ | ||||
|   selector:'df-question', | ||||
|   templateUrl:'app/dynamic-form-question.component.html' | ||||
|   selector: 'df-question', | ||||
|   templateUrl: 'app/dynamic-form-question.component.html' | ||||
| }) | ||||
| export class DynamicFormQuestionComponent { | ||||
|   @Input() question:QuestionBase<any>; | ||||
|   @Input() form:ControlGroup; | ||||
|   @Input() question: QuestionBase<any>; | ||||
|   @Input() form: ControlGroup; | ||||
|   get isValid() { return this.form.controls[this.question.key].valid; } | ||||
| } | ||||
|  | ||||
| @ -7,8 +7,8 @@ import { QuestionControlService }       from './question-control.service'; | ||||
| import { DynamicFormQuestionComponent } from './dynamic-form-question.component'; | ||||
| 
 | ||||
| @Component({ | ||||
|   selector:'dynamic-form', | ||||
|   templateUrl:'app/dynamic-form.component.html', | ||||
|   selector: 'dynamic-form', | ||||
|   templateUrl: 'app/dynamic-form.component.html', | ||||
|   directives: [DynamicFormQuestionComponent], | ||||
|   providers:  [QuestionControlService] | ||||
| }) | ||||
| @ -20,7 +20,7 @@ export class DynamicForm { | ||||
| 
 | ||||
|   constructor(private qcs: QuestionControlService) {  } | ||||
| 
 | ||||
|   ngOnInit(){ | ||||
|   ngOnInit() { | ||||
|     this.form = this.qcs.toControlGroup(this.questions); | ||||
|   } | ||||
| 
 | ||||
|  | ||||
| @ -3,4 +3,4 @@ import { bootstrap }    from '@angular/platform-browser-dynamic'; | ||||
| import { AppComponent } from './app.component'; | ||||
| 
 | ||||
| bootstrap(AppComponent, []) | ||||
|   .catch((err:any) => console.error(err)); | ||||
|   .catch((err: any) => console.error(err)); | ||||
|  | ||||
| @ -1,20 +1,20 @@ | ||||
| // #docregion
 | ||||
| export class QuestionBase<T>{ | ||||
|   value:T; | ||||
|   key:string; | ||||
|   label:string; | ||||
|   required:boolean; | ||||
|   order:number; | ||||
|   controlType:string; | ||||
|   value: T; | ||||
|   key: string; | ||||
|   label: string; | ||||
|   required: boolean; | ||||
|   order: number; | ||||
|   controlType: string; | ||||
| 
 | ||||
|   constructor(options:{ | ||||
|       value?:T, | ||||
|       key?:string, | ||||
|       label?:string, | ||||
|       required?:boolean, | ||||
|       order?:number, | ||||
|       controlType?:string | ||||
|     } = {}){ | ||||
|   constructor(options: { | ||||
|       value?: T, | ||||
|       key?: string, | ||||
|       label?: string, | ||||
|       required?: boolean, | ||||
|       order?: number, | ||||
|       controlType?: string | ||||
|     } = {}) { | ||||
|     this.value = options.value; | ||||
|     this.key = options.key || ''; | ||||
|     this.label = options.label || ''; | ||||
|  | ||||
| @ -5,9 +5,9 @@ import { QuestionBase } from './question-base'; | ||||
| 
 | ||||
| @Injectable() | ||||
| export class QuestionControlService { | ||||
|   constructor(private fb:FormBuilder){ } | ||||
|   constructor(private fb: FormBuilder) { } | ||||
| 
 | ||||
|   toControlGroup(questions:QuestionBase<any>[] ) { | ||||
|   toControlGroup(questions: QuestionBase<any>[] ) { | ||||
|     let group = {}; | ||||
| 
 | ||||
|     questions.forEach(question => { | ||||
|  | ||||
| @ -1,11 +1,11 @@ | ||||
| // #docregion
 | ||||
| import { QuestionBase } from './question-base'; | ||||
| 
 | ||||
| export class DropdownQuestion extends QuestionBase<string>{ | ||||
| export class DropdownQuestion extends QuestionBase<string> { | ||||
|   controlType = 'dropdown'; | ||||
|   options:{key:string, value:string}[] = []; | ||||
|   options: {key: string, value: string}[] = []; | ||||
| 
 | ||||
|   constructor(options:{} = {}){ | ||||
|   constructor(options: {} = {}) { | ||||
|     super(options); | ||||
|     this.options = options['options'] || []; | ||||
|   } | ||||
|  | ||||
| @ -1,11 +1,11 @@ | ||||
| // #docregion
 | ||||
| import { QuestionBase } from './question-base'; | ||||
| 
 | ||||
| export class TextboxQuestion extends QuestionBase<string>{ | ||||
| export class TextboxQuestion extends QuestionBase<string> { | ||||
|   controlType = 'textbox'; | ||||
|   type:string; | ||||
|   type: string; | ||||
| 
 | ||||
|   constructor(options:{} = {}){ | ||||
|   constructor(options: {} = {}) { | ||||
|     super(options); | ||||
|     this.type = options['type'] || ''; | ||||
|   } | ||||
|  | ||||
| @ -13,36 +13,36 @@ export class QuestionService { | ||||
|   // Todo: make asynchronous
 | ||||
|   getQuestions() { | ||||
| 
 | ||||
|     let questions:QuestionBase<any>[] = [ | ||||
|     let questions: QuestionBase<any>[] = [ | ||||
| 
 | ||||
|       new DropdownQuestion({ | ||||
|         key:'brave', | ||||
|         key: 'brave', | ||||
|         label: 'Bravery Rating', | ||||
|         options: [ | ||||
|           {key:'solid',  value:'Solid'}, | ||||
|           {key:'great',  value:'Great'}, | ||||
|           {key:'good',   value:'Good'}, | ||||
|           {key:'unproven',value:'Unproven'} | ||||
|           {key: 'solid',  value: 'Solid'}, | ||||
|           {key: 'great',  value: 'Great'}, | ||||
|           {key: 'good',   value: 'Good'}, | ||||
|           {key: 'unproven', value: 'Unproven'} | ||||
|         ], | ||||
|         order: 3 | ||||
|       }), | ||||
| 
 | ||||
|       new TextboxQuestion({ | ||||
|         key:'firstName', | ||||
|         label:'First name', | ||||
|         value:'Bombasto', | ||||
|         key: 'firstName', | ||||
|         label: 'First name', | ||||
|         value: 'Bombasto', | ||||
|         required: true, | ||||
|         order: 1 | ||||
|       }), | ||||
| 
 | ||||
|       new TextboxQuestion({ | ||||
|         key:'emailAddress', | ||||
|         label:'Email', | ||||
|         key: 'emailAddress', | ||||
|         label: 'Email', | ||||
|         type: 'email', | ||||
|         order: 2 | ||||
|       }) | ||||
|     ]; | ||||
| 
 | ||||
|     return questions.sort((a,b) => a.order - b.order); | ||||
|     return questions.sort((a, b) => a.order - b.order); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,3 +1,4 @@ | ||||
| /* tslint:disable */ | ||||
| // #docregion
 | ||||
| import { bootstrap } from '@angular/platform-browser-dynamic'; | ||||
| 
 | ||||
|  | ||||
| @ -21,11 +21,11 @@ export class TitleComponent { | ||||
|   constructor( | ||||
|     @Inject('titlePrefix') | ||||
|     @Optional() | ||||
|       private titlePrefix:string, | ||||
|       private titlePrefix: string, | ||||
|     @Attribute('title') | ||||
|       private title:string, | ||||
|       private title: string, | ||||
|     @Query('okMsg') | ||||
|       private msg:QueryList<ElementRef>) { | ||||
|       private msg: QueryList<ElementRef>) { | ||||
|   } | ||||
| 
 | ||||
|   ok() { | ||||
|  | ||||
| @ -8,7 +8,7 @@ import { Component, Inject } from '@angular/core'; | ||||
| export class HeroComponent { | ||||
|   constructor( | ||||
|     @Inject('heroName') | ||||
|       private name:string) { | ||||
|       private name: string) { | ||||
|   } | ||||
| } | ||||
| // #enddocregion
 | ||||
|  | ||||
| @ -8,8 +8,8 @@ import { DataService } from './data.service'; | ||||
|   template: `<h1>Hero: {{name}}</h1>` | ||||
| }) | ||||
| export class HeroComponent { | ||||
|   name:string; | ||||
|   constructor(dataService:DataService) { | ||||
|   name: string; | ||||
|   constructor(dataService: DataService) { | ||||
|     this.name = dataService.getHeroName(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -13,8 +13,8 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; | ||||
|   ` | ||||
| }) | ||||
| export class ConfirmComponent { | ||||
|   @Input() okMsg:string; | ||||
|   @Input('cancelMsg') notOkMsg:string; | ||||
|   @Input() okMsg: string; | ||||
|   @Input('cancelMsg') notOkMsg: string; | ||||
|   @Output() ok = | ||||
|     new EventEmitter(); | ||||
|   @Output('cancel') notOk = | ||||
| @ -44,8 +44,8 @@ export class ConfirmComponent { | ||||
|   directives: [ConfirmComponent] | ||||
| }) | ||||
| export class AppComponent { | ||||
|   okClicked:boolean; | ||||
|   cancelClicked:boolean; | ||||
|   okClicked: boolean; | ||||
|   cancelClicked: boolean; | ||||
| 
 | ||||
|   onOk() { | ||||
|     this.okClicked = true; | ||||
|  | ||||
| @ -11,7 +11,7 @@ import { Component, OnInit } | ||||
| // #docregion
 | ||||
| export class HeroComponent | ||||
|     implements OnInit { | ||||
|   name:string; | ||||
|   name: string; | ||||
|   ngOnInit() { | ||||
|     this.name = 'Windstorm'; | ||||
|   } | ||||
|  | ||||
| @ -4,14 +4,14 @@ import { Component } from '@angular/core'; | ||||
| 
 | ||||
| @Component({ | ||||
|   selector: 'hero-view', | ||||
|   template:  | ||||
|   template: | ||||
|     '<h1>Hero: {{getName()}}</h1>' | ||||
| }) | ||||
| // #docregion appexport
 | ||||
| // #docregion class
 | ||||
| export class HeroComponent { | ||||
|   title = 'Hero Detail'; | ||||
|   getName() {return 'Windstorm';} | ||||
|   getName() {return 'Windstorm'; } | ||||
| } | ||||
| // #enddocregion class
 | ||||
| // #enddocregion appexport
 | ||||
|  | ||||
| @ -10,8 +10,8 @@ import { Component, HostBinding, HostListener } from '@angular/core'; | ||||
| export class HeroesComponent { | ||||
|   @HostBinding() title = 'Tooltip content'; | ||||
|   @HostBinding('class.heading') | ||||
|     hClass = true | ||||
|   active:boolean; | ||||
|     hClass = true; | ||||
|   active: boolean; | ||||
| 
 | ||||
|   constructor() {} | ||||
| 
 | ||||
| @ -21,7 +21,7 @@ export class HeroesComponent { | ||||
|   } | ||||
| 
 | ||||
|   @HostListener('dblclick', ['$event']) | ||||
|   doubleClicked(evt:Event) { | ||||
|   doubleClicked(evt: Event) { | ||||
|     this.active = true; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -14,7 +14,7 @@ import { | ||||
|   </span>` | ||||
| }) | ||||
| class ActiveLabelComponent { | ||||
|   active:boolean; | ||||
|   active: boolean; | ||||
| 
 | ||||
|   activate() { | ||||
|     this.active = true; | ||||
| @ -30,11 +30,11 @@ class ActiveLabelComponent { | ||||
|   </h2>` | ||||
| }) | ||||
| class HeroComponent { | ||||
|   @Input() hero:any; | ||||
|   active:boolean; | ||||
|   @Input() hero: any; | ||||
|   active: boolean; | ||||
| 
 | ||||
|   @ContentChild(ActiveLabelComponent) | ||||
|   label:ActiveLabelComponent | ||||
|   label: ActiveLabelComponent; | ||||
| 
 | ||||
|   activate() { | ||||
|     this.active = true; | ||||
| @ -68,7 +68,7 @@ export class HeroesQueriesComponent { | ||||
|   ]; | ||||
| 
 | ||||
|   @ViewChildren(HeroComponent) | ||||
|   heroCmps:QueryList<HeroComponent>; | ||||
|   heroCmps: QueryList<HeroComponent>; | ||||
| 
 | ||||
|   activate() { | ||||
|     this.heroCmps.forEach( | ||||
|  | ||||
| @ -1,8 +1,6 @@ | ||||
| // #docregion ng2import
 | ||||
| import { bootstrap } | ||||
|   from '@angular/platform-browser-dynamic'; | ||||
| import { | ||||
| } from '@angular/router'; | ||||
| import { | ||||
|   LocationStrategy, | ||||
|   HashLocationStrategy | ||||
|  | ||||
| @ -16,7 +16,7 @@ export class HeroAppComponent { | ||||
|   hero = new Hero( | ||||
|     'Human Torch', | ||||
|     ['Mister Fantastic', 'Invisible Woman', 'Thing'] | ||||
|   ) | ||||
|   ); | ||||
| 
 | ||||
|   @HostBinding('class') get themeClass() { | ||||
|     return 'theme-light'; | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| export class Hero { | ||||
|   active:boolean; | ||||
|   active: boolean; | ||||
| 
 | ||||
|   constructor(public name:string, | ||||
|               public team:string[]) { | ||||
|   constructor(public name: string, | ||||
|               public team: string[]) { | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -123,7 +123,7 @@ describe('Dependency Injection Tests', function () { | ||||
|     it('P10 (optional dependency) displays as expected', function () { | ||||
|       expectedMsg = 'Optional logger was not available'; | ||||
|       expect(element(by.css('#p10')).getText()).toEqual(expectedMsg); | ||||
|     }) | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   describe('User/Heroes:', function() { | ||||
| @ -163,8 +163,8 @@ describe('Dependency Injection Tests', function () { | ||||
|     describe('after button click', function() { | ||||
| 
 | ||||
|       beforeAll(function (done) { | ||||
|         let buttonEle = element.all(by.cssContainingText('button','Next User')).get(0); | ||||
|         buttonEle.click().then(done,done); | ||||
|         let buttonEle = element.all(by.cssContainingText('button', 'Next User')).get(0); | ||||
|         buttonEle.click().then(done, done); | ||||
|       }); | ||||
| 
 | ||||
|       it('User is Alice  - authorized', function () { | ||||
|  | ||||
| @ -13,7 +13,7 @@ import { HeroesComponent }   from './heroes/heroes.component.1'; | ||||
|     <my-car></my-car> | ||||
|     <my-heroes></my-heroes> | ||||
|   `,
 | ||||
|   directives:[CarComponent, HeroesComponent] | ||||
|   directives: [CarComponent, HeroesComponent] | ||||
| }) | ||||
| 
 | ||||
| export class AppComponent { | ||||
|  | ||||
| @ -17,7 +17,7 @@ import { Logger }            from './logger.service'; | ||||
|     <my-car></my-car> | ||||
|     <my-heroes></my-heroes> | ||||
|   `,
 | ||||
|   directives:[CarComponent, HeroesComponent], | ||||
|   directives: [CarComponent, HeroesComponent], | ||||
|   providers: [ | ||||
|     Logger, | ||||
|    // #docregion providers
 | ||||
| @ -26,10 +26,10 @@ import { Logger }            from './logger.service'; | ||||
|   ] | ||||
| }) | ||||
| export class AppComponent { | ||||
|   title:string; | ||||
|   title: string; | ||||
| 
 | ||||
|   // #docregion ctor
 | ||||
|   constructor(@Inject(APP_CONFIG) config:AppConfig) { | ||||
|   constructor(@Inject(APP_CONFIG) config: AppConfig) { | ||||
|     this.title = config.title; | ||||
|   } | ||||
|   // #enddocregion ctor
 | ||||
|  | ||||
| @ -31,7 +31,7 @@ import { ProvidersComponent } from './providers.component'; | ||||
|     <my-heroes id="authorized" *ngIf="isAuthorized"></my-heroes> | ||||
|     <my-heroes id="unauthorized" *ngIf="!isAuthorized"></my-heroes> | ||||
|   `,
 | ||||
|   directives:[CarComponent, HeroesComponent, | ||||
|   directives: [CarComponent, HeroesComponent, | ||||
|               InjectorComponent, TestComponent, ProvidersComponent], | ||||
|   // #docregion providers
 | ||||
|   providers: [ | ||||
| @ -42,22 +42,22 @@ import { ProvidersComponent } from './providers.component'; | ||||
|   // #enddocregion providers
 | ||||
| }) | ||||
| export class AppComponent { | ||||
|   title:string; | ||||
|   title: string; | ||||
| 
 | ||||
|   // #docregion ctor
 | ||||
|   constructor( | ||||
|     @Inject(APP_CONFIG) config:AppConfig, | ||||
|     @Inject(APP_CONFIG) config: AppConfig, | ||||
|     private userService: UserService) { | ||||
|     this.title = config.title; | ||||
|   } | ||||
|   // #enddocregion ctor
 | ||||
| 
 | ||||
|   get isAuthorized() { return this.user.isAuthorized;} | ||||
|   get isAuthorized() { return this.user.isAuthorized; } | ||||
|   nextUser()         { this.userService.getNewUser(); } | ||||
|   get user()         { return this.userService.user; } | ||||
| 
 | ||||
|   get userInfo()     { | ||||
|     return `Current user, ${this.user.name}, is `+ | ||||
|     return `Current user, ${this.user.name}, is ` + | ||||
|            `${this.isAuthorized ? '' : 'not'} authorized. `; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -4,10 +4,10 @@ import { OpaqueToken } from '@angular/core'; | ||||
| export let APP_CONFIG = new OpaqueToken('app.config'); | ||||
| // #enddocregion token
 | ||||
| 
 | ||||
| //#docregion config
 | ||||
| // #docregion config
 | ||||
| export interface AppConfig { | ||||
|   apiEndpoint: string, | ||||
|   title: string | ||||
|   apiEndpoint: string; | ||||
|   title: string; | ||||
| } | ||||
| 
 | ||||
| export const HERO_DI_CONFIG: AppConfig = { | ||||
|  | ||||
| @ -5,42 +5,42 @@ import { Car, Engine, Tires } from './car'; | ||||
| 
 | ||||
| ///////// example 1 ////////////
 | ||||
| export function simpleCar() { | ||||
|   //#docregion car-ctor-instantiation
 | ||||
|   // #docregion car-ctor-instantiation
 | ||||
|   // Simple car with 4 cylinders and Flintstone tires.
 | ||||
|   var car = new Car(new Engine(), new Tires()); | ||||
|   //#enddocregion car-ctor-instantiation
 | ||||
|   let car = new Car(new Engine(), new Tires()); | ||||
|   // #enddocregion car-ctor-instantiation
 | ||||
|   car.description = 'Simple'; | ||||
|   return car; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| ///////// example 2 ////////////
 | ||||
| //#docregion car-ctor-instantiation-with-param
 | ||||
| // #docregion car-ctor-instantiation-with-param
 | ||||
|   class Engine2 { | ||||
|     constructor(public cylinders: number) { } | ||||
|   } | ||||
| //#enddocregion car-ctor-instantiation-with-param
 | ||||
| // #enddocregion car-ctor-instantiation-with-param
 | ||||
| export function superCar() { | ||||
| //#docregion car-ctor-instantiation-with-param
 | ||||
| // #docregion car-ctor-instantiation-with-param
 | ||||
|   // Super car with 12 cylinders and Flintstone tires.
 | ||||
|   var bigCylinders = 12; | ||||
|   var car = new Car(new Engine2(bigCylinders), new Tires()); | ||||
| //#enddocregion car-ctor-instantiation-with-param
 | ||||
|   let bigCylinders = 12; | ||||
|   let car = new Car(new Engine2(bigCylinders), new Tires()); | ||||
| // #enddocregion car-ctor-instantiation-with-param
 | ||||
|   car.description = 'Super'; | ||||
|   return car; | ||||
| } | ||||
| 
 | ||||
| /////////// example 3 //////////
 | ||||
|   //#docregion car-ctor-instantiation-with-mocks
 | ||||
|   // #docregion car-ctor-instantiation-with-mocks
 | ||||
|   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() { | ||||
|   //#docregion car-ctor-instantiation-with-mocks
 | ||||
|   // #docregion car-ctor-instantiation-with-mocks
 | ||||
|   // Test car with 8 cylinders and YokoGoodStone tires.
 | ||||
|   var car = new Car(new MockEngine(), new MockTires()); | ||||
|   //#enddocregion car-ctor-instantiation-with-mocks
 | ||||
|   let car = new Car(new MockEngine(), new MockTires()); | ||||
|   // #enddocregion car-ctor-instantiation-with-mocks
 | ||||
|   car.description = 'Test'; | ||||
|   return car; | ||||
| } | ||||
|  | ||||
| @ -5,23 +5,23 @@ import { Logger }             from '../logger.service'; | ||||
| 
 | ||||
| // #docregion injector
 | ||||
| export function useInjector() { | ||||
|   var injector: ReflectiveInjector; | ||||
|   let injector: ReflectiveInjector; | ||||
|   // #enddocregion injector
 | ||||
|   /* | ||||
|   // #docregion injector-no-new
 | ||||
|   // Cannot instantiate an ReflectiveInjector like this!
 | ||||
|   var injector = new ReflectiveInjector([Car, Engine, Tires]); | ||||
|   let injector = new ReflectiveInjector([Car, Engine, Tires]); | ||||
|   // #enddocregion injector-no-new
 | ||||
|   */ | ||||
|   // #docregion injector, injector-create-and-call
 | ||||
|   injector = ReflectiveInjector.resolveAndCreate([Car, Engine, Tires]); | ||||
|   // #docregion injector-call
 | ||||
|   var car = injector.get(Car); | ||||
|   let car = injector.get(Car); | ||||
|   // #enddocregion injector-call, injector-create-and-call
 | ||||
|   car.description = 'Injector'; | ||||
| 
 | ||||
|   injector = ReflectiveInjector.resolveAndCreate([Logger]); | ||||
|   var logger = injector.get(Logger); | ||||
|   logger.log('Injector car.drive() said: '+car.drive()); | ||||
|   let logger = injector.get(Logger); | ||||
|   logger.log('Injector car.drive() said: ' + car.drive()); | ||||
|   return car; | ||||
| } | ||||
|  | ||||
| @ -1,10 +1,10 @@ | ||||
| // Car without DI
 | ||||
| import { Engine, Tires } from './car'; | ||||
| 
 | ||||
| //#docregion car
 | ||||
| // #docregion car
 | ||||
| export class Car { | ||||
| 
 | ||||
|   //#docregion car-ctor
 | ||||
|   // #docregion car-ctor
 | ||||
|   public engine: Engine; | ||||
|   public tires: Tires; | ||||
|   public description = 'No DI'; | ||||
| @ -13,12 +13,12 @@ export class Car { | ||||
|     this.engine = new Engine(); | ||||
|     this.tires = new Tires(); | ||||
|   } | ||||
|   //#enddocregion car-ctor
 | ||||
|   // #enddocregion car-ctor
 | ||||
| 
 | ||||
|   // Method using the engine and tires
 | ||||
|   drive() { | ||||
|     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
 | ||||
|  | ||||
| @ -11,7 +11,7 @@ export class Tires { | ||||
| 
 | ||||
| @Injectable() | ||||
| export class Car { | ||||
|   //#docregion car-ctor
 | ||||
|   // #docregion car-ctor
 | ||||
|   public description = 'DI'; | ||||
| 
 | ||||
|   constructor(public engine: Engine, public tires: Tires) { } | ||||
| @ -20,6 +20,6 @@ export class Car { | ||||
|   // Method using the engine and tires
 | ||||
|   drive() { | ||||
|     return `${this.description} car with ` + | ||||
|       `${this.engine.cylinders} cylinders and ${this.tires.make} tires.` | ||||
|       `${this.engine.cylinders} cylinders and ${this.tires.make} tires.`; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,3 +1,4 @@ | ||||
| /* tslint:disable:one-line */ | ||||
| // #docregion
 | ||||
| import { Component }   from '@angular/core'; | ||||
| 
 | ||||
|  | ||||
| @ -8,12 +8,12 @@ import { Logger }     from '../logger.service'; | ||||
| @Injectable() | ||||
| export class HeroService { | ||||
| 
 | ||||
|   //#docregion ctor
 | ||||
|   // #docregion ctor
 | ||||
|   constructor(private logger: Logger) {  } | ||||
|   //#enddocregion ctor
 | ||||
|   // #enddocregion ctor
 | ||||
| 
 | ||||
|   getHeroes() { | ||||
|     this.logger.log('Getting heroes ...') | ||||
|     this.logger.log('Getting heroes ...'); | ||||
|     return HEROES; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,3 +1,4 @@ | ||||
| /* tslint:disable:one-line */ | ||||
| // #docregion
 | ||||
| import { HeroService } from './hero.service'; | ||||
| import { Logger }      from '../logger.service'; | ||||
| @ -6,7 +7,7 @@ import { UserService } from '../user.service'; | ||||
| // #docregion factory
 | ||||
| let heroServiceFactory = (logger: Logger, userService: UserService) => { | ||||
|   return new HeroService(logger, userService.user.isAuthorized); | ||||
| } | ||||
| }; | ||||
| // #enddocregion factory
 | ||||
| 
 | ||||
| // #docregion provider
 | ||||
|  | ||||
| @ -7,7 +7,7 @@ import { Logger }     from '../logger.service'; | ||||
| 
 | ||||
| @Injectable() | ||||
| export class HeroService { | ||||
|   private _user:string; | ||||
|   private _user: string; | ||||
| 
 | ||||
|   // #docregion internals
 | ||||
|   constructor( | ||||
| @ -15,7 +15,7 @@ export class HeroService { | ||||
|     private isAuthorized: boolean) { } | ||||
| 
 | ||||
|   getHeroes() { | ||||
|     let auth = this.isAuthorized ? 'authorized ': 'unauthorized'; | ||||
|     let auth = this.isAuthorized ? 'authorized ' : 'unauthorized'; | ||||
|     this.logger.log(`Getting heroes for ${auth} user.`); | ||||
|     return HEROES.filter(hero => this.isAuthorized || !hero.isSecret); | ||||
|   } | ||||
|  | ||||
| @ -21,8 +21,8 @@ import { HeroService }        from './hero.service'; | ||||
|   <hero-list></hero-list> | ||||
|   `,
 | ||||
|   // #enddocregion v1
 | ||||
|   providers:[HeroService], | ||||
|   providers: [HeroService], | ||||
|   // #docregion v1
 | ||||
|   directives:[HeroListComponent] | ||||
|   directives: [HeroListComponent] | ||||
| }) | ||||
| export class HeroesComponent { } | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
| import { Component }          from '@angular/core'; | ||||
| 
 | ||||
| import { HeroListComponent }  from './hero-list.component'; | ||||
| import { heroServiceProvider} from './hero.service.provider'; | ||||
| import { heroServiceProvider } from './hero.service.provider'; | ||||
| 
 | ||||
| @Component({ | ||||
|   selector: 'my-heroes', | ||||
| @ -10,7 +10,7 @@ import { heroServiceProvider} from './hero.service.provider'; | ||||
|   <h2>Heroes</h2> | ||||
|   <hero-list></hero-list> | ||||
|   `,
 | ||||
|   providers:[heroServiceProvider], | ||||
|   directives:[HeroListComponent] | ||||
|   providers: [heroServiceProvider], | ||||
|   directives: [HeroListComponent] | ||||
| }) | ||||
| export class HeroesComponent { } | ||||
|  | ||||
| @ -2,14 +2,14 @@ | ||||
| import { Hero } from './hero'; | ||||
| 
 | ||||
| export var HEROES: Hero[] = [ | ||||
|   { id: 11, isSecret: false, name: "Mr. Nice" }, | ||||
|   { id: 12, isSecret: false, name: "Narco" }, | ||||
|   { id: 13, isSecret: false, name: "Bombasto" }, | ||||
|   { id: 14, isSecret: false, name: "Celeritas" }, | ||||
|   { id: 15, isSecret: false, name: "Magneta" }, | ||||
|   { id: 16, isSecret: false, name: "RubberMan" }, | ||||
|   { id: 17, isSecret: false, name: "Dynama" }, | ||||
|   { id: 18, isSecret: true,  name: "Dr IQ" }, | ||||
|   { id: 19, isSecret: true,  name: "Magma" }, | ||||
|   { id: 20, isSecret: true,  name: "Tornado" } | ||||
|   { id: 11, isSecret: false, name: 'Mr. Nice' }, | ||||
|   { id: 12, isSecret: false, name: 'Narco' }, | ||||
|   { id: 13, isSecret: false, name: 'Bombasto' }, | ||||
|   { id: 14, isSecret: false, name: 'Celeritas' }, | ||||
|   { id: 15, isSecret: false, name: 'Magneta' }, | ||||
|   { id: 16, isSecret: false, name: 'RubberMan' }, | ||||
|   { id: 17, isSecret: false, name: 'Dynama' }, | ||||
|   { id: 18, isSecret: true,  name: 'Dr IQ' }, | ||||
|   { id: 19, isSecret: true,  name: 'Magma' }, | ||||
|   { id: 20, isSecret: true,  name: 'Tornado' } | ||||
| ]; | ||||
|  | ||||
| @ -20,8 +20,6 @@ import { Logger }               from './logger.service'; | ||||
|   providers: [Car, Engine, Tires, heroServiceProvider, Logger] | ||||
| }) | ||||
| export class InjectorComponent { | ||||
|   constructor(private injector: Injector) { } | ||||
| 
 | ||||
|   car: Car = this.injector.get(Car); | ||||
| 
 | ||||
|   // #docregion get-hero-service
 | ||||
| @ -29,8 +27,10 @@ export class InjectorComponent { | ||||
|   // #enddocregion get-hero-service
 | ||||
|   hero: Hero = this.heroService.getHeroes()[0]; | ||||
| 
 | ||||
|   constructor(private injector: Injector) { } | ||||
| 
 | ||||
|   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); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -3,7 +3,7 @@ import { Injectable } from '@angular/core'; | ||||
| 
 | ||||
| @Injectable() | ||||
| export class Logger { | ||||
|   logs:string[] = []; // capture logs for testing
 | ||||
|   logs: string[] = []; // capture logs for testing
 | ||||
| 
 | ||||
|   log(message: string) { | ||||
|     this.logs.push(message); | ||||
|  | ||||
| @ -1,3 +1,4 @@ | ||||
| /* tslint:disable:no-unused-variable */ | ||||
| import { bootstrap }    from '@angular/platform-browser-dynamic'; | ||||
| import { AppComponent } from './app.component.1'; | ||||
| import { HeroService }  from './heroes/hero.service.1'; | ||||
| @ -5,9 +6,8 @@ import { HeroService }  from './heroes/hero.service.1'; | ||||
| bootstrap(AppComponent); | ||||
| 
 | ||||
| function discouraged() { | ||||
|   //#docregion bootstrap
 | ||||
|   // #docregion bootstrap-discouraged
 | ||||
|   bootstrap(AppComponent, | ||||
|            [HeroService]); // DISCOURAGED (but works)不推荐(但可用)
 | ||||
|   //#enddocregion bootstrap
 | ||||
|            [HeroService]); // DISCOURAGED (but works)
 | ||||
|   // #enddocregion bootstrap-discouraged
 | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -2,7 +2,7 @@ import { bootstrap }          from '@angular/platform-browser-dynamic'; | ||||
| import { AppComponent }       from './app.component'; | ||||
| import { ProvidersComponent } from './providers.component'; | ||||
| 
 | ||||
| //#docregion bootstrap
 | ||||
| // #docregion bootstrap
 | ||||
| bootstrap(AppComponent); | ||||
| //#enddocregion bootstrap
 | ||||
| // #enddocregion bootstrap
 | ||||
| bootstrap(ProvidersComponent); | ||||
|  | ||||
| @ -235,8 +235,9 @@ export class ProviderComponent10 { | ||||
|   log: string; | ||||
|   // #docregion provider-10-ctor
 | ||||
|   constructor(@Optional() private logger: Logger) { | ||||
|     if (this.logger) | ||||
|     if (this.logger) { | ||||
|       this.logger.log(some_message); | ||||
|     } | ||||
|   } | ||||
|   // #enddocregion provider-10-ctor
 | ||||
| 
 | ||||
|  | ||||
| @ -1,3 +1,4 @@ | ||||
| /* tslint:disable */ | ||||
| // Simulate a simple test
 | ||||
| // Reader should look to the testing chapter for the real thing
 | ||||
| 
 | ||||
| @ -20,15 +21,15 @@ export class TestComponent { | ||||
| /////////////////////////////////////
 | ||||
| function runTests() { | ||||
| 
 | ||||
|   //#docregion spec
 | ||||
|   // #docregion spec
 | ||||
|   let expectedHeroes = [{name: 'A'}, {name: 'B'}] | ||||
|   let mockService = <HeroService> {getHeroes: () => expectedHeroes } | ||||
| 
 | ||||
|   it("should have heroes when HeroListComponent created", () => { | ||||
|   it('should have heroes when HeroListComponent created', () => { | ||||
|     let hlc = new HeroListComponent(mockService); | ||||
|     expect(hlc.heroes.length).toEqual(expectedHeroes.length); | ||||
|   }) | ||||
|   //#enddocregion spec
 | ||||
|   }); | ||||
|   // #enddocregion spec
 | ||||
| 
 | ||||
|   return testResults; | ||||
| } | ||||
| @ -36,19 +37,19 @@ function runTests() { | ||||
| //////////////////////////////////
 | ||||
| // Fake Jasmine infrastructure
 | ||||
| var testName: string; | ||||
| var testResults: {pass:string; message:string}; | ||||
| var testResults: {pass: string; message: string}; | ||||
| 
 | ||||
| function expect(actual:any) { | ||||
| function expect(actual: any) { | ||||
|   return { | ||||
|     toEqual: function(expected:any){ | ||||
|       testResults = actual === expected? | ||||
|         {pass:'passed', message: testName} : | ||||
|         {pass:'failed', message: `${testName}; expected ${actual} to equal ${expected}.`}; | ||||
|     toEqual: function(expected: any){ | ||||
|       testResults = actual === expected ? | ||||
|         {pass: 'passed', message: testName} : | ||||
|         {pass: 'failed', message: `${testName}; expected ${actual} to equal ${expected}.`}; | ||||
|     } | ||||
|   } | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| function it(label:string, test: () => void) { | ||||
| function it(label: string, test: () => void) { | ||||
|   testName = label; | ||||
|   test(); | ||||
| } | ||||
|  | ||||
| @ -1,10 +1,10 @@ | ||||
| // #docregion
 | ||||
| import {Injectable} from '@angular/core'; | ||||
| import { Injectable } from '@angular/core'; | ||||
| 
 | ||||
| export class User { | ||||
|   constructor( | ||||
|     public name:string, | ||||
|     public isAuthorized:boolean = false) { } | ||||
|     public name: string, | ||||
|     public isAuthorized = false) { } | ||||
| } | ||||
| 
 | ||||
| // Todo: get the user; don't 'new' it.
 | ||||
|  | ||||
| @ -17,4 +17,4 @@ export class AppCtorComponent { | ||||
|     this.myHero = 'Windstorm'; | ||||
|   } | ||||
| } | ||||
| // #enddocregion app-ctor
 | ||||
| // #enddocregion app-ctor
 | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| // #docregion
 | ||||
| import { Component} from '@angular/core'; | ||||
| import { Component } from '@angular/core'; | ||||
| // #docregion import-hero
 | ||||
| import { Hero} from './hero'; | ||||
| import { Hero } from './hero'; | ||||
| // #enddocregion import-hero
 | ||||
| 
 | ||||
| @Component({ | ||||
|  | ||||
| @ -2,8 +2,8 @@ | ||||
| export class Hero { | ||||
|   constructor( | ||||
|     // #docregion id-parameter
 | ||||
|     public id:number, | ||||
|     public id: number, | ||||
|     // #enddocregion id-parameter
 | ||||
|     public name:string) { } | ||||
|     public name: string) { } | ||||
| } | ||||
| // #enddocregion
 | ||||
| // #enddocregion
 | ||||
|  | ||||
| @ -1,3 +1,4 @@ | ||||
| /* tslint:disable */ | ||||
| import { bootstrap } from '@angular/platform-browser-dynamic'; | ||||
| 
 | ||||
| import { AppCtorComponent } from './app-ctor.component'; | ||||
| @ -8,9 +9,9 @@ import { AppComponent as v3 } from './app.component.3'; | ||||
| import { AppComponent as final } from './app.component'; | ||||
| 
 | ||||
| // pick one
 | ||||
| //bootstrap(v1);
 | ||||
| //bootstrap(v2);
 | ||||
| //bootstrap(v3);
 | ||||
| // bootstrap(v1);
 | ||||
| // bootstrap(v2);
 | ||||
| // bootstrap(v3);
 | ||||
| bootstrap(final); | ||||
| 
 | ||||
| // for doc testing
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| // #docregion
 | ||||
| import { Component }         from '@angular/core'; | ||||
| import { HeroFormComponent } from './hero-form.component' | ||||
| import { HeroFormComponent } from './hero-form.component'; | ||||
| 
 | ||||
| @Component({ | ||||
|   selector: 'my-app', | ||||
|  | ||||
| @ -41,7 +41,7 @@ export class HeroFormComponent { | ||||
|     this.model = new Hero(42, '', ''); | ||||
|   // #enddocregion new-hero-v1
 | ||||
|     this.active = false; | ||||
|     setTimeout(()=> this.active=true, 0); | ||||
|     setTimeout(() => this.active = true, 0); | ||||
|   // #docregion new-hero-v1
 | ||||
|   } | ||||
|   // #enddocregion new-hero-v1
 | ||||
| @ -51,7 +51,7 @@ export class HeroFormComponent { | ||||
| 
 | ||||
|   // Reveal in html:
 | ||||
|   //   Name via form.controls = {{showFormControls(heroForm)}}
 | ||||
|   showFormControls(form:NgForm){ | ||||
|   showFormControls(form: NgForm) { | ||||
| 
 | ||||
|     return form && form.controls['name'] && | ||||
|     // #docregion form-controls
 | ||||
|  | ||||
| @ -6,8 +6,8 @@ describe('Hierarchical dependency injection', function () { | ||||
|   }); | ||||
| 
 | ||||
|   it('should open with a card view', function () { | ||||
|     expect(element.all(by.cssContainingText('button','edit')).get(0).isDisplayed()).toBe(true, | ||||
|       "edit button should be displayed"); | ||||
|     expect(element.all(by.cssContainingText('button', 'edit')).get(0).isDisplayed()).toBe(true, | ||||
|       'edit button should be displayed'); | ||||
|   }); | ||||
| 
 | ||||
|   it('should have multiple heroes listed', function () { | ||||
| @ -15,10 +15,10 @@ describe('Hierarchical dependency injection', 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() { | ||||
|       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 () { | ||||
| @ -34,11 +34,11 @@ describe('Hierarchical dependency injection', function () { | ||||
|     let heroEle = element.all(by.css('heroes-list li')).get(1); | ||||
|     // get the 2nd span which is the name of the hero
 | ||||
|     let heroNameEle = heroEle.all(by.css('hero-card span')).get(1); | ||||
|     let editButtonEle = heroEle.element(by.cssContainingText('button','edit')); | ||||
|     let editButtonEle = heroEle.element(by.cssContainingText('button', 'edit')); | ||||
|     editButtonEle.click().then(function() { | ||||
|       let inputEle = heroEle.element(by.css('hero-editor input')); | ||||
|       // return inputEle.sendKeys("foo");
 | ||||
|       return sendKeys(inputEle, "foo"); | ||||
|       return sendKeys(inputEle, 'foo'); | ||||
|     }).then(function() { | ||||
|       let buttonName = shouldSave ? 'save' : 'cancel'; | ||||
|       let buttonEle = heroEle.element(by.cssContainingText('button', buttonName)); | ||||
| @ -49,7 +49,7 @@ describe('Hierarchical dependency injection', function () { | ||||
|       } else { | ||||
|         expect(heroNameEle.getText()).not.toContain('foo'); | ||||
|       } | ||||
|     }) | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| // #docregion
 | ||||
| export class EditItem<T> { | ||||
|   editing: boolean | ||||
|   editing: boolean; | ||||
|   constructor (public item: T) {} | ||||
| } | ||||
| // #docregion
 | ||||
|  | ||||
| @ -2,8 +2,8 @@ import { Hero } from './hero'; | ||||
| 
 | ||||
| export class HeroesService { | ||||
|   heroes: Array<Hero> = [ | ||||
|     { name: "RubberMan", power: 'flexibility'}, | ||||
|     { name: "Tornado", power: 'Weather changer'} | ||||
|     { name: 'RubberMan', power: 'flexibility'}, | ||||
|     { name: 'Tornado', power: 'Weather changer'} | ||||
|   ]; | ||||
| 
 | ||||
|   getHeroes () { | ||||
|  | ||||
| @ -4,7 +4,7 @@ import { bootstrap }           from '@angular/platform-browser-dynamic'; | ||||
| import { HeroesListComponent } from './heroes-list.component'; | ||||
| import { HeroesService }       from './heroes.service'; | ||||
| 
 | ||||
| bootstrap(HeroesListComponent, [HeroesService]) | ||||
| bootstrap(HeroesListComponent, [HeroesService]); | ||||
| 
 | ||||
| /* Documentation artifact below | ||||
| // #docregion bad-alternative
 | ||||
|  | ||||
| @ -8,16 +8,16 @@ export class RestoreService<T> { | ||||
|     this.currentItem = this.clone(item); | ||||
|   } | ||||
| 
 | ||||
|   getItem () :T { | ||||
|   getItem (): T { | ||||
|     return this.currentItem; | ||||
|   } | ||||
| 
 | ||||
|   restoreItem () :T { | ||||
|   restoreItem (): T { | ||||
|     this.currentItem = this.originalItem; | ||||
|     return this.getItem(); | ||||
|   } | ||||
| 
 | ||||
|   clone (item: T) :T { | ||||
|   clone (item: T): T { | ||||
|     // super poor clone implementation
 | ||||
|     return JSON.parse(JSON.stringify(item)); | ||||
|   } | ||||
|  | ||||
| @ -10,7 +10,7 @@ describe('Homepage Hello World', function () { | ||||
|   it(`should display the label: ${expectedLabel}`, function () { | ||||
|     expect(element(by.css('label')).getText()).toEqual(expectedLabel); | ||||
|   }); | ||||
|    | ||||
| 
 | ||||
|   it('should display entered name', function () { | ||||
|     let testName = 'Bobby Joe'; | ||||
|     let nameEle = element.all(by.css('input')).get(0); | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| // #docregion
 | ||||
| // Declare an interaface for type safety
 | ||||
| export interface Todo { | ||||
|   text: string, | ||||
|   done: boolean | ||||
|   text: string; | ||||
|   done: boolean; | ||||
| } | ||||
|  | ||||
| @ -14,7 +14,7 @@ import { TodoForm }  from './todo_form'; | ||||
| 
 | ||||
|     <todo-list [todos]="todos"></todo-list> | ||||
|     <todo-form (newTask)="addTask($event)"></todo-form>`, | ||||
|   styles:['a { cursor: pointer; cursor: hand; }'], | ||||
|   styles: ['a { cursor: pointer; cursor: hand; }'], | ||||
|   directives: [TodoList, TodoForm] | ||||
| }) | ||||
| export class TodoApp { | ||||
|  | ||||
| @ -17,7 +17,7 @@ export class TodoForm { | ||||
| 
 | ||||
|   addTodo() { | ||||
|     if (this.task) { | ||||
|       this.newTask.next({text:this.task, done:false}); | ||||
|       this.newTask.next({text: this.task, done: false}); | ||||
|     } | ||||
|     this.task = ''; | ||||
|   } | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| // #docregion
 | ||||
| import { Component, Input } from '@angular/core'; | ||||
| 
 | ||||
| import { Todo } from './todo'; | ||||
| 
 | ||||
| @Component({ | ||||
|  | ||||
| @ -11,22 +11,22 @@ describe('Lifecycle hooks', function () { | ||||
| 
 | ||||
|   it('should support peek-a-boo', function () { | ||||
|     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 updateHeroButton = element.all(by.css('peek-a-boo-parent button')).get(1); | ||||
|     expect(pabButton.getText()).toContain('Create Peek'); | ||||
|     pabButton.click().then(function () { | ||||
|       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()).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(); | ||||
|     }).then(function () { | ||||
|       expect(pabComp.getText()).toContain('Windstorm!'); | ||||
|       return pabButton.click(); | ||||
|     }).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')); | ||||
| 
 | ||||
|     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 () {
 | ||||
|     sendKeys(heroNameInputEle, '-foo-').then(function () { | ||||
|       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.
 | ||||
|       // return powerInputEle.sendKeys('-bar-');
 | ||||
|       return sendKeys(powerInputEle, '-bar-'); | ||||
|     }).then(function () { | ||||
|       expect(titleEle.getText()).toContain('Windstorm-foo- can sing-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'); | ||||
|     changeLogEles.count().then(function(count) { | ||||
|       // 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; | ||||
|       // heroNameInputEle.sendKeys('-foo-').then(function () {
 | ||||
|       return sendKeys(heroNameInputEle, '-foo-') | ||||
|       return sendKeys(heroNameInputEle, '-foo-'); | ||||
|     }).then(function () { | ||||
|       expect(titleEle.getText()).toContain('Windstorm-foo- can sing'); | ||||
|       return changeLogEles.count() | ||||
|       return changeLogEles.count(); | ||||
|     }).then(function (count) { | ||||
|       // 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; | ||||
|       // return powerInputEle.sendKeys('-bar-');
 | ||||
|       return sendKeys(powerInputEle, '-bar-'); | ||||
| @ -99,18 +99,18 @@ describe('Lifecycle hooks', function () { | ||||
| 
 | ||||
|     logEles.count().then(function(count) { | ||||
|       logCount = count; | ||||
|       return sendKeys(childViewInputEle, "-test-"); | ||||
|       return sendKeys(childViewInputEle, '-test-'); | ||||
|     }).then(function() { | ||||
|       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'); | ||||
|       return logEles.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; | ||||
|       return buttonEle.click(); | ||||
|     }).then(function() { | ||||
|       expect(logEles.count()).toBeLessThan(logCount, "log should shrink after reset"); | ||||
|       expect(logEles.count()).toBeLessThan(logCount, 'log should shrink after reset'); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
| @ -128,30 +128,30 @@ describe('Lifecycle hooks', function () { | ||||
| 
 | ||||
|     logEles.count().then(function(count) { | ||||
|       logCount = count; | ||||
|       return sendKeys(childViewInputEle, "-test-"); | ||||
|       return sendKeys(childViewInputEle, '-test-'); | ||||
|     }).then(function() { | ||||
|       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'); | ||||
|       return logEles.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; | ||||
|       return buttonEle.click(); | ||||
|     }).then(function() { | ||||
|       expect(logEles.count()).toBeLessThan(logCount, "log should shrink after reset"); | ||||
|       expect(logEles.count()).toBeLessThan(logCount, 'log should shrink after reset'); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   it('should support spy\'s OnInit & OnDestroy hooks', function () { | ||||
|     let inputEle = element(by.css('spy-parent input')); | ||||
|     let addHeroButtonEle = element(by.cssContainingText('spy-parent button','Add Hero')); | ||||
|     let resetHeroesButtonEle = element(by.cssContainingText('spy-parent button','Reset Heroes')); | ||||
|     let addHeroButtonEle = element(by.cssContainingText('spy-parent button', 'Add Hero')); | ||||
|     let resetHeroesButtonEle = element(by.cssContainingText('spy-parent button', 'Reset Heroes')); | ||||
|     let heroEles = element.all(by.css('spy-parent div[mySpy')); | ||||
|     let logEles = element.all(by.css('spy-parent h4 ~ div')); | ||||
|     expect(heroEles.count()).toBe(2, 'should have two heroes displayed'); | ||||
|     expect(logEles.count()).toBe(2, 'should have two log entries'); | ||||
|     sendKeys(inputEle, "-test-").then(function() { | ||||
|     sendKeys(inputEle, '-test-').then(function() { | ||||
|       return addHeroButtonEle.click(); | ||||
|     }).then(function() { | ||||
|       expect(heroEles.count()).toBe(3, 'should have added one hero'); | ||||
| @ -161,12 +161,12 @@ describe('Lifecycle hooks', function () { | ||||
|     }).then(function() { | ||||
|       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'); | ||||
|     }) | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   it('should support "spy counter"', function () { | ||||
|     let updateCounterButtonEle = element(by.cssContainingText('counter-parent button','Update')); | ||||
|     let resetCounterButtonEle = element(by.cssContainingText('counter-parent button','Reset')); | ||||
|     let updateCounterButtonEle = element(by.cssContainingText('counter-parent button', 'Update')); | ||||
|     let resetCounterButtonEle = element(by.cssContainingText('counter-parent button', 'Reset')); | ||||
|     let textEle = element(by.css('counter-parent my-counter > div')); | ||||
|     let logEles = element.all(by.css('counter-parent h4 ~ div')); | ||||
|     expect(textEle.getText()).toContain('Counter = 0'); | ||||
| @ -178,8 +178,6 @@ describe('Lifecycle hooks', function () { | ||||
|     }).then(function() { | ||||
|       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'); | ||||
|     }) | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
| 
 | ||||
| }); | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user