refactor(core): introduce APP_BOOTSTRAP_LISTENER multi provider

Using the `registerBootstrapListener` easily lead to race condition
and needed dependencies on `ApplicationRef`.

BREAKING CHANGE:
- `ApplicationRef.registerBootstrapListener` is deprecated. Provide a multi
  provider for the new token `APP_BOOTSTRAP_LISTENER` instead.
This commit is contained in:
Tobias Bosch
2016-08-02 05:22:44 -07:00
parent 8e6091de6c
commit af2e80e068
6 changed files with 88 additions and 50 deletions

View File

@ -7,7 +7,7 @@
*/
import {Location, LocationStrategy, PathLocationStrategy} from '@angular/common';
import {ANALYZE_FOR_ENTRY_COMPONENTS, APP_INITIALIZER, ApplicationRef, ComponentResolver, Injector, NgModuleFactoryLoader, OpaqueToken, SystemJsNgModuleLoader} from '@angular/core';
import {ANALYZE_FOR_ENTRY_COMPONENTS, APP_BOOTSTRAP_LISTENER, APP_INITIALIZER, ApplicationRef, ComponentResolver, Injector, NgModuleFactoryLoader, OpaqueToken, SystemJsNgModuleLoader} from '@angular/core';
import {Routes} from './config';
import {Router} from './router';
@ -53,12 +53,8 @@ export function rootRoute(router: Router): ActivatedRoute {
return router.routerState.root;
}
export function setupRouterInitializer(injector: Injector) {
return () => {
injector.get(ApplicationRef).registerBootstrapListener(() => {
injector.get(Router).initialNavigation();
});
};
export function initialRouterNavigation(router: Router) {
return () => { router.initialNavigation(); };
}
/**
@ -102,11 +98,19 @@ export function provideRouter(routes: Routes, config: ExtraOptions = {}): any[]
RouterOutletMap, {provide: ActivatedRoute, useFactory: rootRoute, deps: [Router]},
// Trigger initial navigation
{provide: APP_INITIALIZER, multi: true, useFactory: setupRouterInitializer, deps: [Injector]},
{provide: NgModuleFactoryLoader, useClass: SystemJsNgModuleLoader}
provideRouterInitializer(), {provide: NgModuleFactoryLoader, useClass: SystemJsNgModuleLoader}
];
}
export function provideRouterInitializer() {
return {
provide: APP_BOOTSTRAP_LISTENER,
multi: true,
useFactory: initialRouterNavigation,
deps: [Router]
};
}
/**
* Router configuration.
*

View File

@ -9,7 +9,7 @@
import {APP_BASE_HREF, HashLocationStrategy, Location, LocationStrategy, PathLocationStrategy, PlatformLocation} from '@angular/common';
import {ApplicationRef, ComponentResolver, Inject, Injector, ModuleWithProviders, NgModule, NgModuleFactoryLoader, OpaqueToken, Optional, SystemJsNgModuleLoader} from '@angular/core';
import {ExtraOptions, ROUTER_CONFIGURATION, provideRouterConfig, provideRoutes, rootRoute, setupRouter} from './common_router_providers';
import {ExtraOptions, ROUTER_CONFIGURATION, provideRouterConfig, provideRouterInitializer, provideRoutes, rootRoute, setupRouter} from './common_router_providers';
import {Routes} from './config';
import {RouterLink, RouterLinkWithHref} from './directives/router_link';
import {RouterLinkActive} from './directives/router_link_active';
@ -76,13 +76,6 @@ export const ROUTER_PROVIDERS: any[] = [
*/
@NgModule({declarations: ROUTER_DIRECTIVES, exports: ROUTER_DIRECTIVES})
export class RouterModule {
constructor(private injector: Injector, appRef: ApplicationRef) {
// do the initialization only once
if ((<any>injector).parent.get(RouterModule, null)) return;
appRef.registerBootstrapListener(() => { injector.get(Router).initialNavigation(); });
}
static forRoot(routes: Routes, config?: ExtraOptions): ModuleWithProviders {
return {
ngModule: RouterModule,
@ -94,7 +87,8 @@ export class RouterModule {
deps: [
PlatformLocation, [new Inject(APP_BASE_HREF), new Optional()], ROUTER_CONFIGURATION
]
}
},
provideRouterInitializer()
]
};
}