feat(router): Make RootRouter disposable to allow cleanup of Location subscription. ROUTER_PROVIDERS now automatically disposes of the RootRouter when the application is disposed.

Closes #4915
This commit is contained in:
Alex Rickabaugh 2015-10-26 11:01:02 -07:00
parent 2674eaca51
commit 2e059dc916
3 changed files with 27 additions and 11 deletions

View File

@ -113,12 +113,12 @@ export const ROUTER_PROVIDERS: any[] = CONST_EXPR([
RouteRegistry, RouteRegistry,
CONST_EXPR(new Provider(LocationStrategy, {useClass: PathLocationStrategy})), CONST_EXPR(new Provider(LocationStrategy, {useClass: PathLocationStrategy})),
Location, Location,
CONST_EXPR( CONST_EXPR(new Provider(
new Provider(Router, Router,
{ {
useFactory: routerFactory, useFactory: routerFactory,
deps: CONST_EXPR([RouteRegistry, Location, ROUTER_PRIMARY_COMPONENT]) deps: CONST_EXPR([RouteRegistry, Location, ROUTER_PRIMARY_COMPONENT, ApplicationRef])
})), })),
CONST_EXPR(new Provider( CONST_EXPR(new Provider(
ROUTER_PRIMARY_COMPONENT, ROUTER_PRIMARY_COMPONENT,
{useFactory: routerPrimaryComponentFactory, deps: CONST_EXPR([ApplicationRef])})) {useFactory: routerPrimaryComponentFactory, deps: CONST_EXPR([ApplicationRef])}))
@ -129,8 +129,10 @@ export const ROUTER_PROVIDERS: any[] = CONST_EXPR([
*/ */
export const ROUTER_BINDINGS = ROUTER_PROVIDERS; export const ROUTER_BINDINGS = ROUTER_PROVIDERS;
function routerFactory(registry, location, primaryComponent) { function routerFactory(registry, location, primaryComponent, appRef) {
return new RootRouter(registry, location, primaryComponent); var rootRouter = new RootRouter(registry, location, primaryComponent);
appRef.registerDisposeListener(() => rootRouter.dispose());
return rootRouter;
} }
function routerPrimaryComponentFactory(app) { function routerPrimaryComponentFactory(app) {

View File

@ -467,12 +467,13 @@ export class Router {
export class RootRouter extends Router { export class RootRouter extends Router {
/** @internal */ /** @internal */
_location: Location; _location: Location;
_locationSub: Object;
constructor(registry: RouteRegistry, location: Location, primaryComponent: Type) { constructor(registry: RouteRegistry, location: Location, primaryComponent: Type) {
super(registry, null, primaryComponent); super(registry, null, primaryComponent);
this._location = location; this._location = location;
this._location.subscribe((change) => this._locationSub = this._location.subscribe(
this.navigateByUrl(change['url'], isPresent(change['pop']))); (change) => this.navigateByUrl(change['url'], isPresent(change['pop'])));
this.registry.configFromComponent(primaryComponent); this.registry.configFromComponent(primaryComponent);
this.navigateByUrl(location.path()); this.navigateByUrl(location.path());
} }
@ -489,6 +490,13 @@ export class RootRouter extends Router {
} }
return promise; return promise;
} }
dispose(): void {
if (isPresent(this._locationSub)) {
ObservableWrapper.dispose(this._locationSub);
this._locationSub = null;
}
}
} }
class ChildRouter extends Router { class ChildRouter extends Router {

View File

@ -34,11 +34,17 @@ import {
import {LocationStrategy} from 'angular2/src/router/location_strategy'; import {LocationStrategy} from 'angular2/src/router/location_strategy';
import {MockLocationStrategy} from 'angular2/src/mock/mock_location_strategy'; import {MockLocationStrategy} from 'angular2/src/mock/mock_location_strategy';
import {ApplicationRef} from 'angular2/src/core/application_ref';
import {MockApplicationRef} from 'angular2/src/mock/mock_application_ref';
export function main() { export function main() {
describe('router injectables', () => { describe('router injectables', () => {
beforeEachBindings(() => { beforeEachBindings(() => {
return [ROUTER_PROVIDERS, provide(LocationStrategy, {useClass: MockLocationStrategy})]; return [
ROUTER_PROVIDERS,
provide(LocationStrategy, {useClass: MockLocationStrategy}),
provide(ApplicationRef, {useClass: MockApplicationRef})
];
}); });
// do not refactor out the `bootstrap` functionality. We still want to // do not refactor out the `bootstrap` functionality. We still want to