chore: use the provide object literal
closes #1594 replace `provide(...{use:...})` with `{provide: ..., use...}` syntax
This commit is contained in:
		
							parent
							
								
									6f02f76fc2
								
							
						
					
					
						commit
						c185c3548c
					
				| @ -35,16 +35,11 @@ describe('Dependency Injection Cookbook', function () { | ||||
|       expect(sortedHero).toBeDefined(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should render Hero of the Month when DI deps are defined using provide()', function () { | ||||
|     it('should render Hero of the Month', function () { | ||||
|       let heroOfTheMonth = element.all(by.xpath('//h3[text()="Hero of the month"]')).get(0); | ||||
|       expect(heroOfTheMonth).toBeDefined(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should render Hero of the Month when DI deps are defined using provide object literal', function () { | ||||
|       let heroOfTheMonth = element.all(by.xpath('//h3[text()="Hero of the month 2"]')).get(0); | ||||
|       expect(heroOfTheMonth).toBeDefined(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should render Hero Bios', function () { | ||||
|       let heroBios = element.all(by.xpath('//h3[text()="Hero Bios"]')).get(0); | ||||
|       expect(heroBios).toBeDefined(); | ||||
| @ -60,16 +55,11 @@ describe('Dependency Injection Cookbook', function () { | ||||
|       expect(magmaPhone).toBeDefined(); | ||||
|     }); | ||||
| 
 | ||||
|     it('should render Hero-of-the-Month runner-ups when DI deps are defined using provide()', function () { | ||||
|     it('should render Hero-of-the-Month runner-ups', function () { | ||||
|       let runnersUp =  element(by.id('rups1')).getText(); | ||||
|       expect(runnersUp).toContain('RubberMan, Mr. Nice'); | ||||
|     }); | ||||
| 
 | ||||
|     it('should render Hero-of-the-Month runner-ups when DI deps are defined using provide object literal', function () { | ||||
|       let runnersUp =  element(by.id('rups2')).getText(); | ||||
|       expect(runnersUp).toContain('RubberMan, Mr. Nice'); | ||||
|     }); | ||||
| 
 | ||||
|     it('should render DateLogger log entry in Hero-of-the-Month', function () { | ||||
|       let logs =  element.all(by.id('logs')).get(0).getText(); | ||||
|       expect(logs).toContain('INFO: starting up at'); | ||||
|  | ||||
| @ -23,10 +23,6 @@ | ||||
|   <hero-of-the-month></hero-of-the-month> | ||||
| </div> | ||||
| 
 | ||||
| <div class="di-component"> | ||||
|   <hero-of-the-month-lit></hero-of-the-month-lit> | ||||
| </div> | ||||
| 
 | ||||
| <div class="di-component"> | ||||
|   <h3>Unsorted Heroes</h3> | ||||
|   <unsorted-heroes></unsorted-heroes> | ||||
|  | ||||
| @ -9,13 +9,10 @@ import { HeroesBaseComponent, | ||||
| import { HighlightDirective }          from './highlight.directive'; | ||||
| import { ParentFinderComponent }       from './parent-finder.component'; | ||||
| 
 | ||||
| // Object Literal syntax
 | ||||
| import { HeroOfTheMonthLiteralsComponent } from './hero-of-the-month-literals.component'; | ||||
| 
 | ||||
| const DIRECTIVES = [ | ||||
|     HeroBiosComponent, HeroBiosAndContactsComponent, | ||||
|     HeroesBaseComponent, SortedHeroesComponent, | ||||
|     HeroOfTheMonthComponent, HeroOfTheMonthLiteralsComponent, | ||||
|     HeroOfTheMonthComponent, | ||||
|     HighlightDirective, | ||||
|     ParentFinderComponent | ||||
| ]; | ||||
|  | ||||
| @ -1,67 +0,0 @@ | ||||
| /* tslint:disable:one-line:check-open-brace*/ | ||||
| // #docplaster
 | ||||
| // #docregion opaque-token
 | ||||
| import { OpaqueToken } from '@angular/core'; | ||||
| 
 | ||||
| export const TITLE = new OpaqueToken('title'); | ||||
| // #enddocregion opaque-token
 | ||||
| 
 | ||||
| // #docregion hero-of-the-month
 | ||||
| import { Component, Inject } from '@angular/core'; | ||||
| 
 | ||||
| import { DateLoggerService, | ||||
|          MinimalLogger }     from './date-logger.service'; | ||||
| import { Hero }              from './hero'; | ||||
| import { HeroService }       from './hero.service'; | ||||
| import { LoggerService }     from './logger.service'; | ||||
| import { RUNNERS_UP, | ||||
|          runnersUpFactory }  from './runners-up'; | ||||
| 
 | ||||
| // #enddocregion hero-of-the-month
 | ||||
| // #docregion some-hero
 | ||||
| const someHero = new Hero(42, 'Magma', 'Had a great month!', '555-555-5555'); | ||||
| // #enddocregion some-hero
 | ||||
| 
 | ||||
| const template = ` | ||||
|   <h3>{{title}}</h3> | ||||
|   <div>Winner: <strong>{{heroOfTheMonth.name}}</strong></div> | ||||
|   <div>Reason for award: <strong>{{heroOfTheMonth.description}}</strong></div> | ||||
|   <div>Runners-up: <strong id="rups2">{{runnersUp}}</strong></div> | ||||
| 
 | ||||
|   <p>Logs:</p> | ||||
|   <div id="logs"> | ||||
|     <div *ngFor="let log of logs">{{log}}</div> | ||||
|   </div> | ||||
|   `;
 | ||||
| 
 | ||||
| // #docregion hero-of-the-month
 | ||||
| @Component({ | ||||
|   selector: 'hero-of-the-month-lit', | ||||
|   template: template, | ||||
|   // #docregion providers-using-object-literals
 | ||||
|   providers: [ | ||||
|     {provide: Hero,          useValue:    someHero}, | ||||
|     {provide: TITLE,         useValue:    'Hero of the Month - Object Literals'}, | ||||
|     {provide: HeroService,   useClass:    HeroService}, | ||||
|     {provide: LoggerService, useClass:    DateLoggerService}, | ||||
|     {provide: MinimalLogger, useExisting: LoggerService}, | ||||
|     {provide: RUNNERS_UP,    useFactory:  runnersUpFactory(2), deps: [Hero, HeroService]} | ||||
|   ] | ||||
|   // #enddocregion providers-using-object-literals
 | ||||
| }) | ||||
| export class HeroOfTheMonthLiteralsComponent { | ||||
|   logs: string[] = []; | ||||
| 
 | ||||
| // #docregion ctor-signature
 | ||||
|   constructor( | ||||
|       logger: MinimalLogger, | ||||
|       public heroOfTheMonth: Hero, | ||||
|       @Inject(RUNNERS_UP) public runnersUp: string, | ||||
|       @Inject(TITLE) public title: string) | ||||
| // #enddocregion ctor-signature
 | ||||
|   { | ||||
|     this.logs = logger.logs; | ||||
|     logger.logInfo('starting up'); | ||||
|   } | ||||
| } | ||||
| // #enddocregion hero-of-the-month
 | ||||
| @ -7,7 +7,7 @@ export const TITLE = new OpaqueToken('title'); | ||||
| // #enddocregion opaque-token
 | ||||
| 
 | ||||
| // #docregion hero-of-the-month
 | ||||
| import { Component, Inject, provide } from '@angular/core'; | ||||
| import { Component, Inject } from '@angular/core'; | ||||
| 
 | ||||
| import { DateLoggerService, | ||||
|          MinimalLogger }     from './date-logger.service'; | ||||
| @ -40,20 +40,20 @@ const template = ` | ||||
|   template: template, | ||||
|   providers: [ | ||||
|     // #docregion use-value
 | ||||
|     provide(Hero,          {useValue:    someHero}), | ||||
|     { provide: Hero,          useValue:    someHero }, | ||||
|     // #docregion provide-opaque-token
 | ||||
|     provide(TITLE,         {useValue:   'Hero of the Month'}), | ||||
|     { provide: TITLE,         useValue:   'Hero of the Month' }, | ||||
|     // #enddocregion provide-opaque-token
 | ||||
|     // #enddocregion use-value
 | ||||
|     // #docregion use-class
 | ||||
|     provide(HeroService,   {useClass:    HeroService}), | ||||
|     provide(LoggerService, {useClass:    DateLoggerService}), | ||||
|     { provide: HeroService,   useClass:    HeroService }, | ||||
|     { provide: LoggerService, useClass:    DateLoggerService }, | ||||
|     // #enddocregion use-class
 | ||||
|     // #docregion use-existing
 | ||||
|     provide(MinimalLogger, {useExisting: LoggerService}), | ||||
|     { provide: MinimalLogger, useExisting: LoggerService }, | ||||
|     // #enddocregion use-existing
 | ||||
|     // #docregion provide-opaque-token, use-factory
 | ||||
|     provide(RUNNERS_UP,    {useFactory:  runnersUpFactory(2), deps: [Hero, HeroService]}) | ||||
|     { provide: RUNNERS_UP,    useFactory:  runnersUpFactory(2), deps: [Hero, HeroService] } | ||||
|     // #enddocregion provide-opaque-token, use-factory
 | ||||
|   ] | ||||
| }) | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| // #docregion
 | ||||
| import { bootstrap }        from '@angular/platform-browser-dynamic'; | ||||
| import { provide }          from '@angular/core'; | ||||
| import { XHRBackend }       from '@angular/http'; | ||||
| import { ROUTER_PROVIDERS } from '@angular/router-deprecated'; | ||||
| import { LocationStrategy, | ||||
| @ -15,10 +14,9 @@ import { AppComponent }     from './app.component'; | ||||
| // #docregion bootstrap
 | ||||
| bootstrap(AppComponent, [ | ||||
|   ROUTER_PROVIDERS, | ||||
|   provide(LocationStrategy, | ||||
|          {useClass: HashLocationStrategy}), | ||||
|   { provide: LocationStrategy, useClass: HashLocationStrategy }, | ||||
| 
 | ||||
|   provide(XHRBackend, { useClass: InMemoryBackendService }), // in-mem server
 | ||||
|   provide(SEED_DATA,  { useClass: HeroData }) // in-mem server data
 | ||||
|   { provide: XHRBackend, useClass: InMemoryBackendService }, // in-mem server
 | ||||
|   { provide: SEED_DATA,  useClass: HeroData } // in-mem server data
 | ||||
| ]).catch((err: any) => console.error(err)); | ||||
| // #enddocregion bootstrap
 | ||||
|  | ||||
| @ -22,14 +22,17 @@ const DifferentParent = Parent; | ||||
| const provideParent = | ||||
| // #enddocregion provide-parent, provide-the-parent
 | ||||
| // #docregion provide-parent
 | ||||
|   (component: any, parentType?: any) => | ||||
|     provide(parentType || Parent, { useExisting: forwardRef(() => component) }); | ||||
|   (component: any, parentType?: any) => { | ||||
|     return { provide: parentType || Parent, useExisting: forwardRef(() => component) } | ||||
|   }; | ||||
| // #enddocregion provide-parent
 | ||||
| 
 | ||||
| // Simpler syntax version that always provides the component in the name of `Parent`.
 | ||||
| const provideTheParent = | ||||
| // #docregion provide-the-parent
 | ||||
|   (component: any) => provide(Parent, { useExisting: forwardRef(() => component) }); | ||||
|   (component: any) => { | ||||
|     return { provide: Parent, useExisting: forwardRef(() => component) } | ||||
|   }; | ||||
| // #enddocregion provide-the-parent
 | ||||
| 
 | ||||
| 
 | ||||
| @ -105,7 +108,7 @@ const templateB = ` | ||||
|   selector:   'barry', | ||||
|   template:   templateB, | ||||
|   directives: C_DIRECTIVES, | ||||
|   providers:  [ provide(Parent, { useExisting: forwardRef(() => BarryComponent) }) ] | ||||
|   providers:  [{ provide: Parent, useExisting: forwardRef(() => BarryComponent) }] | ||||
| }) | ||||
| export class BarryComponent implements Parent { | ||||
|   name = 'Barry'; | ||||
| @ -155,7 +158,7 @@ const B_DIRECTIVES = [ BarryComponent, BethComponent, BobComponent ]; | ||||
|     </div>`,
 | ||||
| // #enddocregion alex-1
 | ||||
| // #docregion alex-providers
 | ||||
|   providers: [ provide(Parent, { useExisting: forwardRef(() => AlexComponent) }) ], | ||||
|   providers: [{ provide: Parent, useExisting: forwardRef(() => AlexComponent) }], | ||||
| // #enddocregion alex-providers
 | ||||
| // #docregion alex-1
 | ||||
|   directives: C_DIRECTIVES | ||||
|  | ||||
| @ -4,8 +4,6 @@ | ||||
|   // #enddocregion appimport
 | ||||
| 
 | ||||
|   // #docregion ng2import
 | ||||
|   var provide = | ||||
|     ng.core.provide; | ||||
|   var bootstrap = | ||||
|     ng.platformBrowserDynamic.bootstrap; | ||||
|   var LocationStrategy = | ||||
| @ -25,10 +23,10 @@ | ||||
|     bootstrap(app.HeroDIComponent, [app.DataService]); | ||||
|     bootstrap(app.HeroDIInlineComponent, [app.DataService]); | ||||
|     bootstrap(app.HeroDIInjectComponent, [ | ||||
|       ng.core.provide('heroName', {useValue: 'Windstorm'}) | ||||
|       { provide: 'heroName', useValue: 'Windstorm' } | ||||
|     ]); | ||||
|     bootstrap(app.HeroDIInjectComponent2, [ | ||||
|       ng.core.provide('heroName', {useValue: 'Bombasto'}) | ||||
|       { provide: 'heroName', useValue: 'Bombasto' } | ||||
|     ]); | ||||
|     bootstrap(app.HeroDIInjectAdditionalComponent); | ||||
|     bootstrap(app.HeroIOComponent); | ||||
|  | ||||
| @ -1,6 +1,4 @@ | ||||
| // #docregion ng2import
 | ||||
| import { provide } | ||||
|   from '@angular/core'; | ||||
| import { bootstrap } | ||||
|   from '@angular/platform-browser-dynamic'; | ||||
| import { | ||||
| @ -29,7 +27,7 @@ bootstrap(HeroComponent); | ||||
| bootstrap(HeroLifecycleComponent); | ||||
| bootstrap(HeroDIComponent, [DataService]); | ||||
| bootstrap(HeroDIInjectComponent, [ | ||||
|   provide('heroName', {useValue: 'Windstorm'}) | ||||
|   { provide: 'heroName', useValue: 'Windstorm' } | ||||
| ]); | ||||
| bootstrap(AppDIInjectAdditionalComponent); | ||||
| bootstrap(AppIOComponent); | ||||
|  | ||||
| @ -27,38 +27,6 @@ class ProviderComponent1 { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @Component( | ||||
|     selector: 'provider-2', | ||||
|     template: '{{log}}', | ||||
|     providers: | ||||
|       // #docregion providers-2 | ||||
|       const [const Provider(Logger, useClass: Logger)] | ||||
|       // #enddocregion providers-2 | ||||
| ) | ||||
| class ProviderComponent2 { | ||||
|   String log; | ||||
| 
 | ||||
|   ProviderComponent2(Logger logger) { | ||||
|     logger.log('Hello from logger provided with Provider class and useClass'); | ||||
|     log = logger.logs[0]; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// Component just used to ensure that shared E2E tests pass. | ||||
| @Component( | ||||
|   selector: 'provider-3', | ||||
|   template: '{{log}}', | ||||
|   providers: const [const Provider(Logger, useClass: Logger)] | ||||
| ) | ||||
| class ProviderComponent3 { | ||||
|   String log; | ||||
| 
 | ||||
|   ProviderComponent3(Logger logger) { | ||||
|     logger.log('Hello from logger provided with useClass'); | ||||
|     log = logger.logs[0]; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// Component just used to ensure that shared E2E tests pass. | ||||
| @Component( | ||||
|   selector: 'provider-3a', | ||||
| @ -282,8 +250,6 @@ class ProviderComponent10 implements OnInit { | ||||
|     template: ''' | ||||
|       <h2>Provider variations</h2> | ||||
|       <div id="p1"><provider-1></provider-1></div> | ||||
|       <div id="p2"><provider-2></provider-2></div> | ||||
|       <div id="p3"><provider-3></provider-3></div> | ||||
|       <div id="p3a"><provider-3a></provider-3a></div> | ||||
|       <div id="p4"><provider-4></provider-4></div> | ||||
|       <div id="p5"><provider-5></provider-5></div> | ||||
| @ -295,8 +261,6 @@ class ProviderComponent10 implements OnInit { | ||||
|       <div id="p10"><provider-10></provider-10></div>''', | ||||
|     directives: const [ | ||||
|       ProviderComponent1, | ||||
|       ProviderComponent2, | ||||
|       ProviderComponent3, | ||||
|       ProviderComponent3a, | ||||
|       ProviderComponent4, | ||||
|       ProviderComponent5, | ||||
|  | ||||
| @ -80,18 +80,8 @@ describe('Dependency Injection Tests', function () { | ||||
|       expect(element(by.css('#p1')).getText()).toEqual(expectedMsg); | ||||
|     }); | ||||
| 
 | ||||
|     it('P2 (Provider) displays as expected', function () { | ||||
|       expectedMsg = 'Hello from logger provided with Provider class and useClass'; | ||||
|       expect(element(by.css('#p2')).getText()).toEqual(expectedMsg); | ||||
|     }); | ||||
| 
 | ||||
|     it('P3 (provide) displays as expected', function () { | ||||
|       expectedMsg = 'Hello from logger provided with useClass'; | ||||
|       expect(element(by.css('#p3')).getText()).toEqual(expectedMsg); | ||||
|     }); | ||||
| 
 | ||||
|     it('P3a (provide) displays as expected', function () { | ||||
|       expectedMsg = 'Hello from logger provided with {provide: Logger, useClass: Logger}'; | ||||
|       expectedMsg = 'Hello from logger provided with { provide: Logger, useClass: Logger }'; | ||||
|       expect(element(by.css('#p3a')).getText()).toEqual(expectedMsg); | ||||
|     }); | ||||
| 
 | ||||
|  | ||||
| @ -4,7 +4,7 @@ import { Component }         from '@angular/core'; | ||||
| import { CarComponent }      from './car/car.component'; | ||||
| import { HeroesComponent }   from './heroes/heroes.component.1'; | ||||
| 
 | ||||
| import { provide, Inject }   from '@angular/core'; | ||||
| import { Inject }   from '@angular/core'; | ||||
| import { APP_CONFIG, AppConfig, | ||||
|          HERO_DI_CONFIG }    from './app.config'; | ||||
| import { Logger }            from './logger.service'; | ||||
| @ -21,7 +21,7 @@ import { Logger }            from './logger.service'; | ||||
|   providers: [ | ||||
|     Logger, | ||||
|    // #docregion providers
 | ||||
|     provide(APP_CONFIG, {useValue: HERO_DI_CONFIG}) | ||||
|     { provide: APP_CONFIG, useValue: HERO_DI_CONFIG } | ||||
|    // #enddocregion providers
 | ||||
|   ] | ||||
| }) | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| // #docplaster
 | ||||
| // #docregion
 | ||||
| // #docregion imports
 | ||||
| import { Component, Inject, provide } from '@angular/core'; | ||||
| import { Component, Inject } from '@angular/core'; | ||||
| 
 | ||||
| import { CarComponent }      from './car/car.component'; | ||||
| import { HeroesComponent }   from './heroes/heroes.component'; | ||||
| @ -37,7 +37,7 @@ import { ProvidersComponent } from './providers.component'; | ||||
|   providers: [ | ||||
|     Logger, | ||||
|     UserService, | ||||
|     provide(APP_CONFIG, {useValue: HERO_DI_CONFIG}) | ||||
|     { provide: APP_CONFIG, useValue: HERO_DI_CONFIG } | ||||
|   ] | ||||
|   // #enddocregion providers
 | ||||
| }) | ||||
|  | ||||
| @ -1,6 +1,4 @@ | ||||
| // #docregion
 | ||||
| import { provide }     from '@angular/core'; | ||||
| 
 | ||||
| import { HeroService } from './hero.service'; | ||||
| import { Logger }      from '../logger.service'; | ||||
| import { UserService } from '../user.service'; | ||||
| @ -13,8 +11,8 @@ let heroServiceFactory = (logger: Logger, userService: UserService) => { | ||||
| 
 | ||||
| // #docregion provider
 | ||||
| export let heroServiceProvider = | ||||
|   provide(HeroService, { | ||||
|   { provide: HeroService, | ||||
|     useFactory: heroServiceFactory, | ||||
|     deps: [Logger, UserService] | ||||
|   }); | ||||
|   }; | ||||
| // #enddocregion provider
 | ||||
|  | ||||
| @ -1,8 +1,7 @@ | ||||
| /* tslint:disable:one-line:check-open-brace*/ | ||||
| // Examples of provider arrays
 | ||||
| // #docplaster
 | ||||
| import { Component, Inject, Injectable, | ||||
|          provide, Provider }    from '@angular/core'; | ||||
| import { Component, Inject, Injectable } from '@angular/core'; | ||||
| 
 | ||||
| import { APP_CONFIG, AppConfig, | ||||
|          HERO_DI_CONFIG }       from './app.config'; | ||||
| @ -30,53 +29,19 @@ export class ProviderComponent1 { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| //////////////////////////////////////////
 | ||||
| @Component({ | ||||
|   selector: 'provider-2', | ||||
|   template: template, | ||||
|   providers: | ||||
|     // #docregion providers-2
 | ||||
|     [new Provider(Logger, {useClass: Logger})] | ||||
|     // #enddocregion providers-2
 | ||||
| }) | ||||
| export class ProviderComponent2 { | ||||
|   log: string; | ||||
|   constructor(logger: Logger) { | ||||
|     logger.log('Hello from logger provided with Provider class and useClass'); | ||||
|     this.log = logger.logs[0]; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| //////////////////////////////////////////
 | ||||
| @Component({ | ||||
|   selector: 'provider-3', | ||||
|   template: template, | ||||
|   providers: | ||||
|     // #docregion providers-3
 | ||||
|     [provide(Logger, {useClass: Logger})] | ||||
|     // #enddocregion providers-3
 | ||||
| }) | ||||
| export class ProviderComponent3 { | ||||
|   log: string; | ||||
|   constructor(logger: Logger) { | ||||
|     logger.log('Hello from logger provided with useClass'); | ||||
|     this.log = logger.logs[0]; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| //////////////////////////////////////////
 | ||||
| @Component({ | ||||
|   selector: 'provider-3a', | ||||
|   template: template, | ||||
|   providers: | ||||
|     // #docregion providers-3a
 | ||||
|     [{provide: Logger, useClass: Logger}] | ||||
|     [{ provide: Logger, useClass: Logger }] | ||||
|     // #enddocregion providers-3a
 | ||||
| }) | ||||
| export class ProviderComponent3a { | ||||
|   log: string; | ||||
|   constructor(logger: Logger) { | ||||
|     logger.log('Hello from logger provided with {provide: Logger, useClass: Logger}'); | ||||
|     logger.log('Hello from logger provided with { provide: Logger, useClass: Logger }'); | ||||
|     this.log = logger.logs[0]; | ||||
|   } | ||||
| } | ||||
| @ -89,7 +54,7 @@ class BetterLogger extends Logger {} | ||||
|   template: template, | ||||
|   providers: | ||||
|     // #docregion providers-4
 | ||||
|     [provide(Logger, {useClass: BetterLogger})] | ||||
|     [{ provide: Logger, useClass: BetterLogger }] | ||||
|     // #enddocregion providers-4
 | ||||
| }) | ||||
| export class ProviderComponent4 { | ||||
| @ -119,7 +84,7 @@ class EvenBetterLogger extends Logger { | ||||
|   providers: | ||||
|     // #docregion providers-5
 | ||||
|     [ UserService, | ||||
|       provide(Logger, {useClass: EvenBetterLogger}) ] | ||||
|       { provide: Logger, useClass: EvenBetterLogger }] | ||||
|     // #enddocregion providers-5
 | ||||
| }) | ||||
| export class ProviderComponent5 { | ||||
| @ -146,7 +111,7 @@ class OldLogger { | ||||
|     // #docregion providers-6a
 | ||||
|     [ NewLogger, | ||||
|       // Not aliased! Creates two instances of `NewLogger`
 | ||||
|       provide(OldLogger, {useClass: NewLogger}) ] | ||||
|       { provide: OldLogger, useClass: NewLogger}] | ||||
|     // #enddocregion providers-6a
 | ||||
| }) | ||||
| export class ProviderComponent6a { | ||||
| @ -169,7 +134,7 @@ export class ProviderComponent6a { | ||||
|     // #docregion providers-6b
 | ||||
|     [ NewLogger, | ||||
|       // Alias OldLogger w/ reference to NewLogger
 | ||||
|       provide(OldLogger, {useExisting: NewLogger}) ] | ||||
|       { provide: OldLogger, useExisting: NewLogger}] | ||||
|     // #enddocregion providers-6b
 | ||||
| }) | ||||
| export class ProviderComponent6b { | ||||
| @ -197,7 +162,7 @@ let silentLogger = { | ||||
|   template: template, | ||||
|   providers: | ||||
|     // #docregion providers-7
 | ||||
|     [provide(Logger, {useValue: silentLogger})] | ||||
|     [{ provide: Logger, useValue: silentLogger }] | ||||
|     // #enddocregion providers-7
 | ||||
| }) | ||||
| export class ProviderComponent7 { | ||||
| @ -230,11 +195,11 @@ export class ProviderComponent8 { | ||||
|   /* | ||||
|    // #docregion providers-9-interface
 | ||||
|    // FAIL!  Can't use interface as provider token
 | ||||
|    [provide(AppConfig, {useValue: HERO_DI_CONFIG})] | ||||
|    [{ provide: AppConfig, useValue: HERO_DI_CONFIG })] | ||||
|    // #enddocregion providers-9-interface
 | ||||
|    */ | ||||
|   // #docregion providers-9
 | ||||
|   providers: [provide(APP_CONFIG, {useValue: HERO_DI_CONFIG})] | ||||
|   providers: [{ provide: APP_CONFIG, useValue: HERO_DI_CONFIG }] | ||||
|   // #enddocregion providers-9
 | ||||
| }) | ||||
| export class ProviderComponent9 { | ||||
| @ -257,7 +222,7 @@ export class ProviderComponent9 { | ||||
| // Sample providers 1 to 7 illustrate a required logger dependency.
 | ||||
| // Optional logger, can be null
 | ||||
| // #docregion import-optional
 | ||||
| import {Optional} from '@angular/core'; | ||||
| import { Optional } from '@angular/core'; | ||||
| // #enddocregion import-optional
 | ||||
| 
 | ||||
| let some_message: string = 'Hello from the injected logger'; | ||||
| @ -286,8 +251,6 @@ export class ProviderComponent10 { | ||||
|   template: ` | ||||
|   <h2>Provider variations</h2> | ||||
|   <div id="p1"><provider-1></provider-1></div> | ||||
|   <div id="p2"><provider-2></provider-2></div> | ||||
|   <div id="p3"><provider-3></provider-3></div> | ||||
|   <div id="p3a"><provider-3a></provider-3a></div> | ||||
|   <div id="p4"><provider-4></provider-4></div> | ||||
|   <div id="p5"><provider-5></provider-5></div> | ||||
| @ -300,8 +263,6 @@ export class ProviderComponent10 { | ||||
|   `,
 | ||||
|   directives: [ | ||||
|     ProviderComponent1, | ||||
|     ProviderComponent2, | ||||
|     ProviderComponent3, | ||||
|     ProviderComponent3a, | ||||
|     ProviderComponent4, | ||||
|     ProviderComponent5, | ||||
|  | ||||
| @ -8,7 +8,6 @@ import { bootstrap }         from '@angular/platform-browser-dynamic'; | ||||
| import { ROUTER_PROVIDERS }  from '@angular/router-deprecated'; | ||||
| 
 | ||||
| // Add these symbols to override the `LocationStrategy`
 | ||||
| import { provide }           from '@angular/core'; | ||||
| import { LocationStrategy, | ||||
|         HashLocationStrategy } from '@angular/common'; | ||||
| 
 | ||||
| @ -27,7 +26,6 @@ import { AppComponent as ac } from './app.component.2'; | ||||
| bootstrap(ac, [ | ||||
| // #docregion
 | ||||
|   ROUTER_PROVIDERS, | ||||
|   provide(LocationStrategy, | ||||
|          {useClass: HashLocationStrategy}) // .../#/crisis-center/
 | ||||
|   { provide: LocationStrategy, useClass: HashLocationStrategy } // .../#/crisis-center/
 | ||||
| ]); | ||||
| // #enddocregion
 | ||||
|  | ||||
| @ -8,7 +8,6 @@ import { bootstrap }            from '@angular/platform-browser-dynamic'; | ||||
| import { ROUTER_PROVIDERS }     from '@angular/router'; | ||||
| 
 | ||||
| // Add these symbols to override the `LocationStrategy`
 | ||||
| import { provide }              from '@angular/core'; | ||||
| import { LocationStrategy, | ||||
|          HashLocationStrategy } from '@angular/common'; | ||||
| 
 | ||||
| @ -27,7 +26,6 @@ import {AppComponent as ac} from './app.component.2'; | ||||
| bootstrap(ac, [ | ||||
| // #docregion
 | ||||
|   ROUTER_PROVIDERS, | ||||
|   provide(LocationStrategy, | ||||
|          {useClass: HashLocationStrategy}) // .../#/crisis-center/
 | ||||
|   { provide: LocationStrategy, useClass: HashLocationStrategy } // .../#/crisis-center/
 | ||||
| ]); | ||||
| // #enddocregion
 | ||||
|  | ||||
| @ -1,7 +1,6 @@ | ||||
| // #docplaster
 | ||||
| // #docregion final
 | ||||
| // Imports for loading & configuring the in-memory web api
 | ||||
| import { provide }    from '@angular/core'; | ||||
| import { XHRBackend } from '@angular/http'; | ||||
| 
 | ||||
| import { InMemoryBackendService, | ||||
| @ -24,7 +23,7 @@ bootstrap(AppComponent, [ HTTP_PROVIDERS ]); | ||||
| // #docregion final
 | ||||
| bootstrap(AppComponent, [ | ||||
|     HTTP_PROVIDERS, | ||||
|     provide(XHRBackend, { useClass: InMemoryBackendService }), // in-mem server
 | ||||
|     provide(SEED_DATA,  { useClass: HeroData })                // in-mem server data
 | ||||
|     { provide: XHRBackend, useClass: InMemoryBackendService }, // in-mem server
 | ||||
|     { provide: SEED_DATA,  useClass: HeroData }                // in-mem server data
 | ||||
| ]); | ||||
| // #enddocregion final
 | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
| import { AppComponent } from './app.component'; | ||||
| 
 | ||||
| import { By }                     from '@angular/platform-browser'; | ||||
| import { DebugElement, provide  } from '@angular/core'; | ||||
| import { DebugElement } from '@angular/core'; | ||||
| 
 | ||||
| import { | ||||
|   beforeEach, beforeEachProviders, | ||||
| @ -28,8 +28,8 @@ describe('AppComponent', () => { | ||||
|       .overrideDirective(AppComponent, RouterLink,   MockRouterLink) | ||||
|       .overrideDirective(AppComponent, RouterOutlet, MockRouterOutlet) | ||||
|       .overrideProviders(AppComponent, [ | ||||
|         provide(HeroService, {useClass: MockHeroService}), | ||||
|         provide(Router,      {useClass: MockRouter}), | ||||
|         { provide: HeroService, useClass: MockHeroService}, | ||||
|         { provide: Router,      useClass: MockRouter}, | ||||
|       ]) | ||||
|       .createAsync(AppComponent) | ||||
|       .then(fix => { | ||||
|  | ||||
| @ -27,7 +27,6 @@ import { | ||||
| 
 | ||||
| import { ComponentFixture, TestComponentBuilder } from '@angular/compiler/testing'; | ||||
| 
 | ||||
| import { provide }        from '@angular/core'; | ||||
| import { ViewMetadata }   from '@angular/core'; | ||||
| import { Observable }     from 'rxjs/Rx'; | ||||
| 
 | ||||
| @ -145,7 +144,7 @@ xdescribe('async & inject testing errors', () => { | ||||
|   }, 10000); | ||||
| 
 | ||||
|   describe('using beforeEachProviders', () => { | ||||
|     beforeEachProviders(() => [provide(FancyService, {useValue: new FancyService()})]); | ||||
|     beforeEachProviders(() => [{ provide: FancyService, useValue: new FancyService() }]); | ||||
| 
 | ||||
|     beforeEach( | ||||
|         inject([FancyService], (service: FancyService) => { expect(service.value).toEqual('real value'); })); | ||||
| @ -155,7 +154,7 @@ xdescribe('async & inject testing errors', () => { | ||||
|       it('should fail when the injector has already been used', () => { | ||||
|         patchJasmineBeforeEach(); | ||||
|         expect(() => { | ||||
|           beforeEachProviders(() => [provide(FancyService, {useValue: new FancyService()})]); | ||||
|           beforeEachProviders(() => [{ provide: FancyService, useValue: new FancyService() }]); | ||||
|         }) | ||||
|         .toThrowError('beforeEachProviders was called after the injector had been used ' + | ||||
|                       'in a beforeEach or it block. This invalidates the test injector'); | ||||
|  | ||||
| @ -1,9 +1,9 @@ | ||||
| // Based on https://github.com/angular/angular/blob/master/modules/angular2/test/testing/testing_public_spec.ts
 | ||||
| /* tslint:disable:no-unused-variable */ | ||||
| import { | ||||
|   BadTemplateUrlComp, ButtonComp, | ||||
|   BadTemplateUrl, ButtonComp, | ||||
|   ChildChildComp, ChildComp, ChildWithChildComp, | ||||
|   CompWithCompWithExternalTemplate, ExternalTemplateComp, | ||||
|   ExternalTemplateComp, | ||||
|   FancyService, MockFancyService, | ||||
|   InputComp, | ||||
|   MyIfComp, MyIfChildComp, MyIfParentComp, | ||||
| @ -18,14 +18,11 @@ import { By }           from '@angular/platform-browser'; | ||||
| import { | ||||
|   beforeEach, beforeEachProviders, | ||||
|   describe, ddescribe, xdescribe, | ||||
|   it, iit, xit, | ||||
|   expect, it, iit, xit, | ||||
|   async, inject, | ||||
|   fakeAsync, tick, withProviders | ||||
| } from '@angular/core/testing'; | ||||
| 
 | ||||
| // https://github.com/angular/angular/issues/9017
 | ||||
| import {expect} from './expect-proper'; | ||||
| 
 | ||||
| import { ComponentFixture, TestComponentBuilder } from '@angular/compiler/testing'; | ||||
| 
 | ||||
| import { ViewMetadata }   from '@angular/core'; | ||||
| @ -118,7 +115,7 @@ describe('using the test injector with the inject helper', () => { | ||||
| 
 | ||||
|   describe('setting up Providers with FancyService', () => { | ||||
|     beforeEachProviders(() => [ | ||||
|       {provide: FancyService, useValue: new FancyService()} | ||||
|       { provide: FancyService, useValue: new FancyService() } | ||||
|     ]); | ||||
| 
 | ||||
|     it('should use FancyService', | ||||
| @ -185,42 +182,16 @@ describe('using the test injector with the inject helper', () => { | ||||
|   describe('using `withProviders` for per-test provision', () => { | ||||
|     it('should inject test-local FancyService for this test', | ||||
|       // `withProviders`:  set up providers at individual test level
 | ||||
|       withProviders(() => [{provide: FancyService, useValue: {value: 'fake value'}}]) | ||||
|       withProviders(() => [{ provide: FancyService, useValue: {value: 'fake value' }}]) | ||||
| 
 | ||||
|       // now inject and test
 | ||||
|         .inject([FancyService], (service: FancyService) => { | ||||
|           expect(service.value).toEqual('fake value'); | ||||
|         })); | ||||
|   }); | ||||
| 
 | ||||
| 
 | ||||
|   describe('can spy on FancyService', () => { | ||||
| 
 | ||||
|     let spy: jasmine.Spy; | ||||
|     let value: string; | ||||
| 
 | ||||
|     beforeEachProviders(() => [ | ||||
|       {provide: FancyService, useValue: new FancyService()} | ||||
|     ]); | ||||
| 
 | ||||
|     beforeEach(inject([FancyService], (service: FancyService) => { | ||||
|       spy = spyOn(service, 'getValue').and.callFake(() => 'fake value'); | ||||
|       value = service.getValue(); | ||||
|     })); | ||||
| 
 | ||||
|     it('FancyService.getValue spy should return fake', () => { | ||||
|       expect(value).toBe('fake value'); | ||||
|     }); | ||||
| 
 | ||||
|     it('FancyService.getValue spy should have been called', () => { | ||||
|       expect(spy.calls.count()).toBe(1, 'should be called once'); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| describe('test component builder', function() { | ||||
|   beforeEachProviders(() => [ FancyService ]); | ||||
| 
 | ||||
|   it('should instantiate a component with valid DOM', | ||||
|       async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | ||||
| 
 | ||||
| @ -342,7 +313,7 @@ describe('test component builder', function() { | ||||
| 
 | ||||
|         tcb.overrideProviders( | ||||
|               TestProvidersComp, | ||||
|               [{provide: FancyService, useClass: MockFancyService}] | ||||
|               [{ provide: FancyService, useClass: MockFancyService }] | ||||
|             ) | ||||
|             .createAsync(TestProvidersComp) | ||||
|             .then(fixture => { | ||||
| @ -357,7 +328,7 @@ describe('test component builder', function() { | ||||
| 
 | ||||
|         tcb.overrideViewProviders( | ||||
|               TestViewProvidersComp, | ||||
|               [{provide: FancyService, useClass: MockFancyService}] | ||||
|               [{ provide: FancyService, useClass: MockFancyService }] | ||||
|             ) | ||||
|             .createAsync(TestViewProvidersComp) | ||||
|             .then(fixture => { | ||||
| @ -367,7 +338,7 @@ describe('test component builder', function() { | ||||
|             }); | ||||
|       }))); | ||||
| 
 | ||||
|   it('should allow an external template', | ||||
|   it('should allow an external templateUrl', | ||||
|       async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | ||||
| 
 | ||||
|         tcb.createAsync(ExternalTemplateComp) | ||||
| @ -376,201 +347,130 @@ describe('test component builder', function() { | ||||
|               expect(fixture.nativeElement) | ||||
|                   .toHaveText('from external template\n'); | ||||
|             }); | ||||
|       })), 10000);  // Long timeout because of actual XHR to fetch template.
 | ||||
|       })), 10000);  // Long timeout because this test makes an actual XHR.
 | ||||
| 
 | ||||
|   it('should create a component with a component that has an external template', | ||||
|     async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | ||||
|       tcb.createAsync(CompWithCompWithExternalTemplate) | ||||
|         .then(fixture => { | ||||
|           fixture.detectChanges(); | ||||
|           let h3 = fixture.debugElement.query(By.css('h3')); | ||||
|           expect(h3).not.toBeNull('should create CompWithExtComp component'); | ||||
|         }) | ||||
|         .catch((err) => { | ||||
|           // console.error(err);
 | ||||
|           throw (err); | ||||
|         }); | ||||
|     })), 10000); // Long timeout because of actual XHR to fetch template.
 | ||||
|     describe('(lifecycle hooks w/ MyIfParentComp)', () => { | ||||
|       let fixture: ComponentFixture<MyIfParentComp>; | ||||
|       let parent:  MyIfParentComp; | ||||
|       let child:   MyIfChildComp; | ||||
| 
 | ||||
|       /** | ||||
|        * Get the MyIfChildComp from parent; fail w/ good message if cannot. | ||||
|        */ | ||||
|       function getChild() { | ||||
| 
 | ||||
|   it('should spy on injected component service', | ||||
|       async(inject([TestComponentBuilder, FancyService], | ||||
|         (tcb: TestComponentBuilder, service: FancyService) => { | ||||
|         let childDe: DebugElement; // DebugElement that should hold the MyIfChildComp
 | ||||
| 
 | ||||
|         let spy = spyOn(service, 'getValue').and.callThrough(); | ||||
|         // The Hard Way: requires detailed knowledge of the parent template
 | ||||
|         try { | ||||
|           childDe = fixture.debugElement.children[4].children[0]; | ||||
|         } catch (err) { /* we'll report the error */ } | ||||
| 
 | ||||
|         tcb | ||||
|         .createAsync(ExternalTemplateComp) | ||||
|           .then(fixture => { | ||||
|         // DebugElement.queryAll: if we wanted all of many instances:
 | ||||
|         childDe = fixture.debugElement | ||||
|           .queryAll(function (de) { return de.componentInstance instanceof MyIfChildComp; })[0]; | ||||
| 
 | ||||
|             // let spy = spyOn(service, 'getValue').and.callThrough();
 | ||||
|         // WE'LL USE THIS APPROACH !
 | ||||
|         // DebugElement.query: find first instance (if any)
 | ||||
|         childDe = fixture.debugElement | ||||
|           .query(function (de) { return de.componentInstance instanceof MyIfChildComp; }); | ||||
| 
 | ||||
|             fixture.detectChanges(); | ||||
|             expect(spy.calls.count()).toBe(1, 'should be called once'); | ||||
|           }); | ||||
|       })), 10000);  // Long timeout because of actual XHR to fetch template.
 | ||||
|         if (childDe && childDe.componentInstance) { | ||||
|           child = childDe.componentInstance; | ||||
|         } else { | ||||
|           fail('Unable to find MyIfChildComp within MyIfParentComp'); | ||||
|         } | ||||
| 
 | ||||
|   describe('(lifecycle hooks w/ MyIfParentComp)', () => { | ||||
|     let fixture: ComponentFixture<MyIfParentComp>; | ||||
|     let parent:  MyIfParentComp; | ||||
|     let child:   MyIfChildComp; | ||||
| 
 | ||||
|     /** | ||||
|      * Get the MyIfChildComp from parent; fail w/ good message if cannot. | ||||
|      */ | ||||
|     function getChild() { | ||||
| 
 | ||||
|       let childDe: DebugElement; // DebugElement that should hold the MyIfChildComp
 | ||||
| 
 | ||||
|       // The Hard Way: requires detailed knowledge of the parent template
 | ||||
|       try { | ||||
|         childDe = fixture.debugElement.children[4].children[0]; | ||||
|       } catch (err) { /* we'll report the error */ } | ||||
| 
 | ||||
|       // DebugElement.queryAll: if we wanted all of many instances:
 | ||||
|       childDe = fixture.debugElement | ||||
|         .queryAll(function (de) { return de.componentInstance instanceof MyIfChildComp; })[0]; | ||||
| 
 | ||||
|       // WE'LL USE THIS APPROACH !
 | ||||
|       // DebugElement.query: find first instance (if any)
 | ||||
|       childDe = fixture.debugElement | ||||
|         .query(function (de) { return de.componentInstance instanceof MyIfChildComp; }); | ||||
| 
 | ||||
|       if (childDe && childDe.componentInstance) { | ||||
|         child = childDe.componentInstance; | ||||
|       } else { | ||||
|         fail('Unable to find MyIfChildComp within MyIfParentComp'); | ||||
|         return child; | ||||
|       } | ||||
| 
 | ||||
|       return child; | ||||
|     } | ||||
|       // Create MyIfParentComp TCB and component instance before each test (async beforeEach)
 | ||||
|       beforeEach(async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | ||||
|          tcb.createAsync(MyIfParentComp) | ||||
|             .then(fix => { | ||||
|               fixture = fix; | ||||
|               parent = fixture.debugElement.componentInstance; | ||||
|             }); | ||||
|       }))); | ||||
| 
 | ||||
|     // Create MyIfParentComp TCB and component instance before each test (async beforeEach)
 | ||||
|     beforeEach(async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | ||||
|         tcb.createAsync(MyIfParentComp) | ||||
|           .then(fix => { | ||||
|             fixture = fix; | ||||
|             parent = fixture.debugElement.componentInstance; | ||||
|           }); | ||||
|     }))); | ||||
|       it('should instantiate parent component', () => { | ||||
|         expect(parent).not.toBeNull('parent component should exist'); | ||||
|       }); | ||||
| 
 | ||||
|     it('should instantiate parent component', () => { | ||||
|       expect(parent).not.toBeNull('parent component should exist'); | ||||
|     }); | ||||
|       it('parent component OnInit should NOT be called before first detectChanges()', () => { | ||||
|         expect(parent.ngOnInitCalled).toEqual(false); | ||||
|       }); | ||||
| 
 | ||||
|     it('parent component OnInit should NOT be called before first detectChanges()', () => { | ||||
|       expect(parent.ngOnInitCalled).toEqual(false); | ||||
|     }); | ||||
|       it('parent component OnInit should be called after first detectChanges()', () => { | ||||
|         fixture.detectChanges(); | ||||
|         expect(parent.ngOnInitCalled).toEqual(true); | ||||
|       }); | ||||
| 
 | ||||
|     it('parent component OnInit should be called after first detectChanges()', () => { | ||||
|       fixture.detectChanges(); | ||||
|       expect(parent.ngOnInitCalled).toEqual(true); | ||||
|     }); | ||||
|       it('child component should exist after OnInit', () => { | ||||
|         fixture.detectChanges(); | ||||
|         getChild(); | ||||
|         expect(child instanceof MyIfChildComp).toEqual(true, 'should create child'); | ||||
|       }); | ||||
| 
 | ||||
|     it('child component should exist after OnInit', () => { | ||||
|       fixture.detectChanges(); | ||||
|       getChild(); | ||||
|       expect(child instanceof MyIfChildComp).toEqual(true, 'should create child'); | ||||
|     }); | ||||
|       it('should have called child component\'s OnInit ', () => { | ||||
|         fixture.detectChanges(); | ||||
|         getChild(); | ||||
|         expect(child.ngOnInitCalled).toEqual(true); | ||||
|       }); | ||||
| 
 | ||||
|     it('should have called child component\'s OnInit ', () => { | ||||
|       fixture.detectChanges(); | ||||
|       getChild(); | ||||
|       expect(child.ngOnInitCalled).toEqual(true); | ||||
|     }); | ||||
|       it('child component called OnChanges once', () => { | ||||
|         fixture.detectChanges(); | ||||
|         getChild(); | ||||
|         expect(child.ngOnChangesCounter).toEqual(1); | ||||
|       }); | ||||
| 
 | ||||
|     it('child component called OnChanges once', () => { | ||||
|       fixture.detectChanges(); | ||||
|       getChild(); | ||||
|       expect(child.ngOnChangesCounter).toEqual(1); | ||||
|     }); | ||||
|       it('changed parent value flows to child', () => { | ||||
|         fixture.detectChanges(); | ||||
|         getChild(); | ||||
| 
 | ||||
|     it('changed parent value flows to child', () => { | ||||
|       fixture.detectChanges(); | ||||
|       getChild(); | ||||
| 
 | ||||
|       parent.parentValue = 'foo'; | ||||
|       fixture.detectChanges(); | ||||
| 
 | ||||
|       expect(child.ngOnChangesCounter).toEqual(2, | ||||
|         'expected 2 changes: initial value and changed value'); | ||||
|       expect(child.childValue).toEqual('foo', | ||||
|         'childValue should eq changed parent value'); | ||||
|     }); | ||||
| 
 | ||||
|     it('changed child value flows to parent', async(() => { | ||||
|       fixture.detectChanges(); | ||||
|       getChild(); | ||||
| 
 | ||||
|       child.childValue = 'bar'; | ||||
| 
 | ||||
|       return new Promise(resolve => { | ||||
|         // Wait one JS engine turn!
 | ||||
|         setTimeout(() => resolve(), 0); | ||||
|       }).then(() => { | ||||
|         parent.parentValue = 'foo'; | ||||
|         fixture.detectChanges(); | ||||
| 
 | ||||
|         expect(child.ngOnChangesCounter).toEqual(2, | ||||
|           'expected 2 changes: initial value and changed value'); | ||||
|         expect(parent.parentValue).toEqual('bar', | ||||
|           'parentValue should eq changed parent value'); | ||||
|         expect(child.childValue).toEqual('foo', | ||||
|           'childValue should eq changed parent value'); | ||||
|       }); | ||||
| 
 | ||||
|     })); | ||||
|       it('changed child value flows to parent', async(() => { | ||||
|         fixture.detectChanges(); | ||||
|         getChild(); | ||||
| 
 | ||||
|     it('clicking "Close Child" triggers child OnDestroy', () => { | ||||
|       fixture.detectChanges(); | ||||
|       getChild(); | ||||
|         child.childValue = 'bar'; | ||||
| 
 | ||||
|       let btn = fixture.debugElement.query(By.css('button')); | ||||
|       btn.triggerEventHandler('click', null); | ||||
|         return new Promise(resolve => { | ||||
|           // Wait one JS engine turn!
 | ||||
|           setTimeout(() => resolve(), 0); | ||||
|         }).then(() => { | ||||
|           fixture.detectChanges(); | ||||
| 
 | ||||
|           expect(child.ngOnChangesCounter).toEqual(2, | ||||
|             'expected 2 changes: initial value and changed value'); | ||||
|           expect(parent.parentValue).toEqual('bar', | ||||
|             'parentValue should eq changed parent value'); | ||||
|         }); | ||||
| 
 | ||||
|       })); | ||||
| 
 | ||||
|       it('clicking "Close Child" triggers child OnDestroy', () => { | ||||
|         fixture.detectChanges(); | ||||
|         getChild(); | ||||
| 
 | ||||
|         let btn = fixture.debugElement.query(By.css('button')); | ||||
|         btn.triggerEventHandler('click', null); | ||||
| 
 | ||||
|         fixture.detectChanges(); | ||||
|         expect(child.ngOnDestroyCalled).toEqual(true); | ||||
|       }); | ||||
| 
 | ||||
|       fixture.detectChanges(); | ||||
|       expect(child.ngOnDestroyCalled).toEqual(true); | ||||
|     }); | ||||
| 
 | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| describe('test component builder in beforeEach (comp w/ external template)', function() { | ||||
|   let fixture: ComponentFixture<ExternalTemplateComp>; | ||||
| 
 | ||||
|   beforeEach(async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | ||||
|     tcb.createAsync(ExternalTemplateComp).then(fix => fixture = fix); | ||||
|   })) | ||||
|   ); | ||||
|   // May need Long timeout because this test makes an actual XHR to get template
 | ||||
|   // , 10000); WHY CAN'T I ADD TIMEOUT OVERRIDE
 | ||||
| 
 | ||||
|   it('should allow an external template', () => { | ||||
|     fixture.detectChanges(); | ||||
|     expect(fixture.nativeElement) | ||||
|         .toHaveText('from external template\n'); | ||||
|   }); | ||||
| 
 | ||||
| }); | ||||
| 
 | ||||
| describe('test component builder in beforeEach (comp w/ internal comp w/ external template)', function() { | ||||
|   let fixture: ComponentFixture<CompWithCompWithExternalTemplate>; | ||||
| 
 | ||||
|   beforeEach(async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | ||||
|     tcb.createAsync(CompWithCompWithExternalTemplate).then(fix => fixture = fix) | ||||
|        .catch((err) => { | ||||
|          // console.error(err);
 | ||||
|          throw (err); | ||||
|        }); | ||||
|   })) | ||||
|   ); | ||||
|   // May need Long timeout because this test makes an actual XHR to get template
 | ||||
|   // , 10000); WHY CAN'T I ADD TIMEOUT OVERRIDE
 | ||||
| 
 | ||||
|   it('should allow an external template', () => { | ||||
|     fixture.detectChanges(); | ||||
|     let h3 = fixture.debugElement.query(By.css('h3')); | ||||
|     expect(h3).not.toBeNull('should create CompWithExtComp component'); | ||||
|   }); | ||||
| 
 | ||||
| }); | ||||
| 
 | ||||
| //////// Testing Framework Bugs? /////
 | ||||
| import { HeroService }  from './hero.service'; | ||||
| @ -594,7 +494,7 @@ describe('tcb.overrideProviders', () => { | ||||
| 
 | ||||
|     tcb.overrideProviders( | ||||
|           AnotherProvidersComp, | ||||
|           [{provide: HeroService, useValue: {}}] | ||||
|           [{ provide: HeroService, useValue: {}} ] | ||||
|         ) | ||||
|         .createAsync(AnotherProvidersComp); | ||||
|     }))); | ||||
|  | ||||
| @ -2,7 +2,6 @@ | ||||
| import { DashboardComponent } from './dashboard.component'; | ||||
| 
 | ||||
| import { By }       from '@angular/platform-browser'; | ||||
| import { provide  } from '@angular/core'; | ||||
| 
 | ||||
| import { | ||||
|   beforeEach, beforeEachProviders, | ||||
| @ -74,9 +73,9 @@ describe('DashboardComponent', () => { | ||||
|     beforeEachProviders(() => { | ||||
|       mockHeroService = new MockHeroService(); | ||||
|       return [ | ||||
|         provide(Router,      {useClass: MockRouter}), | ||||
|         provide(MockRouter,  {useExisting: Router}), | ||||
|         provide(HeroService, {useValue: mockHeroService}) | ||||
|         { provide: Router,      useClass: MockRouter}, | ||||
|         { provide: MockRouter,  useExisting: Router}, | ||||
|         { provide: HeroService, useValue: mockHeroService } | ||||
|       ]; | ||||
|     }); | ||||
| 
 | ||||
|  | ||||
| @ -5,7 +5,7 @@ | ||||
| import { Component, OnInit } from '@angular/core'; | ||||
| // #enddocregion import-oninit
 | ||||
| // #docregion import-route-params
 | ||||
| import {RouteParams} from '@angular/router-deprecated'; | ||||
| import { RouteParams } from '@angular/router-deprecated'; | ||||
| // #enddocregion import-route-params
 | ||||
| 
 | ||||
| import { Hero } from './hero'; | ||||
|  | ||||
| @ -8,8 +8,6 @@ import { | ||||
| 
 | ||||
| import { TestComponentBuilder } from '@angular/compiler/testing'; | ||||
| 
 | ||||
| import { provide } from '@angular/core'; | ||||
| 
 | ||||
| import { | ||||
|   MockBackend, | ||||
|   MockConnection } from '@angular/http/testing'; | ||||
| @ -46,7 +44,7 @@ describe('Http-HeroService (mockBackend)', () => { | ||||
| 
 | ||||
|   beforeEachProviders(() => [ | ||||
|     HTTP_PROVIDERS, | ||||
|     provide(XHRBackend, {useClass: MockBackend}) | ||||
|     { provide: XHRBackend, useClass: MockBackend } | ||||
|   ]); | ||||
| 
 | ||||
|   it('can instantiate service when inject service', | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| // #docregion
 | ||||
| import {Pipe, PipeTransform} from '@angular/core'; | ||||
| import { Pipe, PipeTransform } from '@angular/core'; | ||||
| 
 | ||||
| @Pipe({ name: 'my-uppercase' }) | ||||
| export class MyUppercasePipe implements PipeTransform { | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| // #docregion
 | ||||
| // #docregion depends-on-angular
 | ||||
| import {Pipe, PipeTransform} from '@angular/core'; | ||||
| import { Pipe, PipeTransform } from '@angular/core'; | ||||
| // #enddocregion depends-on-angular
 | ||||
| 
 | ||||
| @Pipe({ name: 'my-uppercase' }) | ||||
|  | ||||
| @ -1,7 +1,6 @@ | ||||
| // #docplaster
 | ||||
| // #docregion final
 | ||||
| // Imports for loading & configuring the in-memory web api
 | ||||
| import { provide }    from '@angular/core'; | ||||
| import { XHRBackend } from '@angular/http'; | ||||
| 
 | ||||
| import { InMemoryBackendService, SEED_DATA } from 'angular2-in-memory-web-api'; | ||||
| @ -23,7 +22,7 @@ bootstrap(AppComponent, [ HTTP_PROVIDERS ]); | ||||
| // #docregion final
 | ||||
| bootstrap(AppComponent, [ | ||||
|     HTTP_PROVIDERS, | ||||
|     provide(XHRBackend, { useClass: InMemoryBackendService }), // in-mem server
 | ||||
|     provide(SEED_DATA,  { useClass: InMemoryDataService })     // in-mem server data
 | ||||
|     { provide: XHRBackend, useClass: InMemoryBackendService }, // in-mem server
 | ||||
|     { provide: SEED_DATA, useClass: InMemoryDataService }      // in-mem server data
 | ||||
| ]); | ||||
| // #enddocregion final
 | ||||
|  | ||||
| @ -1,5 +1,4 @@ | ||||
| // #docregion
 | ||||
| import { provide } from '@angular/core'; | ||||
| import { | ||||
|   describe, | ||||
|   beforeEach, | ||||
| @ -29,11 +28,11 @@ describe('Phone', function() { | ||||
|     Phone, | ||||
|     MockBackend, | ||||
|     BaseRequestOptions, | ||||
|     provide(Http, { | ||||
|     { provide: Http, | ||||
|       useFactory: (backend: MockBackend, options: BaseRequestOptions) => | ||||
|                     new Http(backend, options), | ||||
|       deps: [MockBackend, BaseRequestOptions] | ||||
|     }) | ||||
|     } | ||||
|   ]); | ||||
| 
 | ||||
|   beforeEach(inject([MockBackend, Phone], | ||||
|  | ||||
| @ -1,5 +1,4 @@ | ||||
| // #docregion
 | ||||
| import { provide } from '@angular/core'; | ||||
| import { HTTP_PROVIDERS } from '@angular/http'; | ||||
| import { Observable } from 'rxjs/Rx'; | ||||
| 
 | ||||
| @ -35,8 +34,8 @@ class MockPhone extends Phone { | ||||
| describe('PhoneDetailComponent', () => { | ||||
| 
 | ||||
|   beforeEachProviders(() => [ | ||||
|     provide(Phone, {useClass: MockPhone}), | ||||
|     provide('$routeParams', {useValue: {phoneId: 'xyz'}}), | ||||
|     { provide: Phone, useClass: MockPhone }, | ||||
|     { provide: '$routeParams', useValue: {phoneId: 'xyz'}}, | ||||
|     HTTP_PROVIDERS | ||||
|   ]); | ||||
| 
 | ||||
|  | ||||
| @ -1,5 +1,4 @@ | ||||
| // #docregion
 | ||||
| import { provide } from '@angular/core'; | ||||
| import { HTTP_PROVIDERS } from '@angular/http'; | ||||
| import { Observable } from 'rxjs/Rx'; | ||||
| import { | ||||
| @ -32,7 +31,7 @@ class MockPhone extends Phone { | ||||
| describe('PhoneList', () => { | ||||
| 
 | ||||
|   beforeEachProviders(() => [ | ||||
|     provide(Phone, {useClass: MockPhone}), | ||||
|     { provide: Phone, useClass: MockPhone }, | ||||
|     HTTP_PROVIDERS | ||||
|   ]); | ||||
| 
 | ||||
|  | ||||
| @ -1,4 +1,3 @@ | ||||
| import { provide } from '@angular/core'; | ||||
| import { | ||||
|   describe, | ||||
|   beforeEach, | ||||
| @ -23,15 +22,15 @@ describe('Phone', function() { | ||||
|     {name: 'Phone Z', snippet: '', images: []} | ||||
|   ]; | ||||
|   let mockBackend:MockBackend; | ||||
|    | ||||
| 
 | ||||
|   beforeEachProviders(() => [ | ||||
|     Phone, | ||||
|     MockBackend, | ||||
|     BaseRequestOptions, | ||||
|     provide(Http, { | ||||
|     { provide: Http, | ||||
|       useFactory: (backend: MockBackend, options: BaseRequestOptions) => new Http(backend, options), | ||||
|       deps: [MockBackend, BaseRequestOptions] | ||||
|     }) | ||||
|     } | ||||
|   ]); | ||||
| 
 | ||||
|   beforeEach(inject([MockBackend, Phone], (_mockBackend_:MockBackend, _phone_:Phone) => { | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| // #docregion
 | ||||
| // #docregion imports
 | ||||
| import { provide } from '@angular/core'; | ||||
| import { | ||||
|   LocationStrategy, | ||||
|   HashLocationStrategy, | ||||
| @ -17,8 +16,8 @@ import { AppComponent } from './app.component'; | ||||
| bootstrap(AppComponent, [ | ||||
|   HTTP_PROVIDERS, | ||||
|   ROUTER_PROVIDERS, | ||||
|   provide(APP_BASE_HREF, {useValue: '!'}), | ||||
|   provide(LocationStrategy, {useClass: HashLocationStrategy}), | ||||
|   { provide: APP_BASE_HREF, useValue: '!' }, | ||||
|   { provide: LocationStrategy, useClass: HashLocationStrategy }, | ||||
|   Phone | ||||
| ]); | ||||
| // #enddocregion bootstrap
 | ||||
|  | ||||
| @ -1,5 +1,4 @@ | ||||
| // #docregion
 | ||||
| import { provide } from '@angular/core'; | ||||
| import { HTTP_PROVIDERS } from '@angular/http'; | ||||
| // #docregion routeparams
 | ||||
| import { RouteParams } from '@angular/router-deprecated'; | ||||
| @ -41,8 +40,8 @@ describe('PhoneDetailComponent', () => { | ||||
|   // #docregion routeparams
 | ||||
| 
 | ||||
|   beforeEachProviders(() => [ | ||||
|     provide(Phone, {useClass: MockPhone}), | ||||
|     provide(RouteParams, {useValue: new RouteParams({phoneId: 'xyz'})}), | ||||
|     { provide: Phone, useClass: MockPhone }, | ||||
|     { provide: RouteParams, useValue: new RouteParams({phoneId: 'xyz'})}, | ||||
|     HTTP_PROVIDERS | ||||
|   ]); | ||||
|   // #enddocregion routeparams
 | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| // #docregion routestuff
 | ||||
| import { provide, ApplicationRef } from '@angular/core'; | ||||
| import { ApplicationRef } from '@angular/core'; | ||||
| import { LocationStrategy, HashLocationStrategy } from '@angular/common'; | ||||
| import { HTTP_PROVIDERS } from '@angular/http'; | ||||
| import { | ||||
| @ -40,14 +40,14 @@ class MockPhone extends Phone { | ||||
| describe('PhoneList', () => { | ||||
| 
 | ||||
|   // #docregion routestuff
 | ||||
|    | ||||
| 
 | ||||
|   beforeEachProviders(() => [ | ||||
|     provide(Phone, {useClass: MockPhone}), | ||||
|     { provide: Phone, useClass: MockPhone}, | ||||
|     HTTP_PROVIDERS, | ||||
|     ROUTER_PROVIDERS, | ||||
|     provide(ApplicationRef, {useClass: MockApplicationRef}), | ||||
|     provide(ROUTER_PRIMARY_COMPONENT, {useValue: AppComponent}), | ||||
|     provide(LocationStrategy, {useClass: MockLocationStrategy}), | ||||
|     { provide: ApplicationRef, useClass: MockApplicationRef }, | ||||
|     { provide: ROUTER_PRIMARY_COMPONENT, useValue: AppComponent }, | ||||
|     { provide: LocationStrategy, useClass: MockLocationStrategy}, | ||||
|   ]); | ||||
|   // #enddocregion routestuff
 | ||||
| 
 | ||||
|  | ||||
| @ -46,9 +46,6 @@ block real-logger | ||||
| block optional-logger | ||||
|   //- TBC. | ||||
| 
 | ||||
| block provider-function-etc | ||||
|   //- N/A | ||||
| 
 | ||||
| block provider-ctor-args | ||||
|   - var _secondParam = 'named parameter, such as <code>useClass</code>'  | ||||
|   :marked | ||||
| @ -62,10 +59,8 @@ block dart-diff-const-metadata | ||||
|       For that reason, we can't call functions to get values | ||||
|       to use within an annotation. | ||||
|       Instead, we use constant literals or constant constructors. | ||||
|       For example, a TypeScript program might use the | ||||
|       function call `provide(Logger, {useClass: BetterLogger})`, | ||||
|       which is equivalent to the TypeScript code | ||||
|       `new Provider(Logger, {useClass: BetterLogger})`. | ||||
|       For example, a TypeScript program will use the | ||||
|       object literal `{ provide: Logger, useClass: BetterLogger }`. | ||||
|       A Dart annotation would instead use the constant value `const Provider(Logger, useClass: BetterLogger)`. | ||||
| 
 | ||||
| block dart-diff-const-metadata-ctor | ||||
|  | ||||
| @ -23,13 +23,11 @@ include ../_util-fns | ||||
|   [Inject the component's DOM element](#component-element) | ||||
| 
 | ||||
|   [Define dependencies with providers](#providers) | ||||
|   * [The *provide* function](#provide) | ||||
|   * [The *provide* object literal](#provide) | ||||
|   * [useValue - the *value provider*](#usevalue) | ||||
|   * [useClass - the *class provider*](#useclass) | ||||
|   * [useExisting - the *alias provider*](#useexisting) | ||||
|   * [useFactory - the *factory provider*](#usefactory)   | ||||
|    | ||||
|   [Define providers with object literals](#object-literals) | ||||
|   * [useFactory - the *factory provider*](#usefactory) | ||||
| 
 | ||||
|   [Provider token alternatives](#tokens) | ||||
|   * [class-interface](#class-interface) | ||||
| @ -406,12 +404,9 @@ figure.image-display | ||||
| .l-main-section | ||||
| a(id='provide') | ||||
| :marked | ||||
|   #### The *provide* function | ||||
|   #### The *provide* object literal | ||||
|    | ||||
|   The imported Angular `provide` function creates an instance of  | ||||
|   the Angular [Provider](../api/core/Provider-class.html) class. | ||||
|    | ||||
|   The `provide` function takes a *token* and a *definition object*. | ||||
|   The `provide` object literal takes a *token* and a *definition object*. | ||||
|   The *token* is usually a class but [it doesn't have to be](#tokens). | ||||
|    | ||||
|   The *definition* object has one main property, (e.g. `useValue`) that indicates how the provider  | ||||
| @ -543,21 +538,6 @@ a(id='usefactory') | ||||
|     Look at the [live example](/resources/live-examples/cb-dependency-injection/ts/plnkr.html) | ||||
|     for the full source code. | ||||
| 
 | ||||
| <a id="object-literals"></a> | ||||
| .l-main-section | ||||
| :marked | ||||
|   ## Define providers with object literals | ||||
| 
 | ||||
| :marked | ||||
|   In the previous section we learned to use the `provide` method to customize how dependencies are created.  | ||||
|    | ||||
|   Instead of calling the `provide` function, we can configure providers with _object literals_.  | ||||
|   It's a slightly more concise syntax and we don't have to import the `provide` function. | ||||
|    | ||||
|   Here's a set of providers that we saw earlier, re-written with object literals. | ||||
| 
 | ||||
| +makeExample('cb-dependency-injection/ts/app/hero-of-the-month-literals.component.ts','providers-using-object-literals')(format='.')   | ||||
| 
 | ||||
| a(id="tokens") | ||||
| .l-main-section | ||||
| :marked | ||||
| @ -771,7 +751,7 @@ a(id='alex') | ||||
|   Recall that Angular always adds a component instance to its own injector;  | ||||
|   that's why we could inject *Alex* into *Carol* [earlier](#known-parent). | ||||
| 
 | ||||
|   We write an [*alias provider*](#useexisting) — a `provide` function with a `useExisting` definition — | ||||
|   We write an [*alias provider*](#useexisting) — a `provide` object literal with a `useExisting` definition — | ||||
|   that creates an *alternative* way to inject the same component instance | ||||
|   and add that provider to the `providers` array of the `@Component` metadata for the `AlexComponent`: | ||||
| a(id="alex-providers") | ||||
|  | ||||
| @ -508,7 +508,7 @@ code-example(format="nocode"). | ||||
|   What matters is that the injector has a provider to go to when it needs a `Logger`. | ||||
| 
 | ||||
| //- Dart limitation: the provide function isn't const so it cannot be used in an annotation. | ||||
| - var __andProvideFn = _docsFor == 'dart' ? '' : 'and <i>provide</i> function'; | ||||
| - var __andProvideFn = _docsFor == 'dart' ? '' : 'and <i>provide</i> object literal'; | ||||
| #provide | ||||
| :marked | ||||
|   ### The *Provider* class !{__andProvideFn} | ||||
| @ -519,31 +519,12 @@ code-example(format="nocode"). | ||||
| +makeExample('dependency-injection/ts/app/providers.component.ts','providers-1') | ||||
| 
 | ||||
| :marked | ||||
|   This is actually a short-hand expression for a provider registration that creates a new instance of the | ||||
|   [Provider](../api/core/Provider-class.html) class. | ||||
|   This is actually a short-hand expression for a provider registration using the _provider_ object literal. | ||||
| 
 | ||||
| +makeExample('dependency-injection/ts/app/providers.component.ts','providers-2') | ||||
| 
 | ||||
| block provider-function-etc | ||||
|   :marked | ||||
|     The [provide](../api/core/provide-function.html) function is the typical way  | ||||
|     to create a `Provider`: | ||||
| 
 | ||||
|   +makeExample('dependency-injection/ts/app/providers.component.ts','providers-3') | ||||
| 
 | ||||
|   :marked | ||||
|    Or we can declare a provider in an _object literal_ and skip the `provide` function. | ||||
| 
 | ||||
|   +makeExample('dependency-injection/ts/app/providers.component.ts','providers-3a')   | ||||
| 
 | ||||
|   :marked | ||||
|     Pick the syntax that you prefer. They all do the same thing. | ||||
| +makeExample('dependency-injection/ts/app/providers.component.ts','providers-3a') | ||||
| 
 | ||||
| block provider-ctor-args | ||||
|   - var _secondParam = 'provider definition object'; | ||||
|   :marked | ||||
|     In each syntax, we supply two types of values. | ||||
| 
 | ||||
| //- var _secondParam = _docsFor == 'dart' ? 'named parameter, such as <code>useClass</code>' : 'provider definition object'; | ||||
| :marked | ||||
|   The first is the [token](#token) that serves as the key for both locating a dependency value | ||||
|  | ||||
| @ -351,7 +351,7 @@ figure.image-display | ||||
|   Providing the router providers at the root makes the Component Router available everywhere in our application. | ||||
| .l-sub-section | ||||
|   :marked | ||||
|     Learn about providers, the `provide` function, and injected services in the | ||||
|     Learn about providers, the `provide` object literal, and injected services in the | ||||
|     [Dependency Injection chapter](dependency-injection.html). | ||||
| :marked | ||||
|   ### The *AppComponent* shell | ||||
| @ -1472,8 +1472,7 @@ code-example(format=".", language="bash"). | ||||
|   We can go old-school with the `HashLocationStrategy` by | ||||
|   providing it as the router's `LocationStrategy` during application bootstrapping. | ||||
| 
 | ||||
|   First, import the `provide` symbol for Dependency Injection and the | ||||
|   `Location` and `HashLocationStrategy` symbols from the router. | ||||
|   Import the `LocationStrategy` and `HashLocationStrategy` symbols from `@angular/common`. | ||||
|    | ||||
|   Then *override* the default strategy defined in `ROUTE_PROVIDERS` by | ||||
|   providing the `HashLocationStrategy` later in the `bootstrap` providers array argument: | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user