X Tutup
Skip to content

Commit 2e059dc

Browse files
committed
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
1 parent 2674eac commit 2e059dc

File tree

3 files changed

+27
-11
lines changed

3 files changed

+27
-11
lines changed

modules/angular2/router.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,12 @@ export const ROUTER_PROVIDERS: any[] = CONST_EXPR([
113113
RouteRegistry,
114114
CONST_EXPR(new Provider(LocationStrategy, {useClass: PathLocationStrategy})),
115115
Location,
116-
CONST_EXPR(
117-
new Provider(Router,
118-
{
119-
useFactory: routerFactory,
120-
deps: CONST_EXPR([RouteRegistry, Location, ROUTER_PRIMARY_COMPONENT])
121-
})),
116+
CONST_EXPR(new Provider(
117+
Router,
118+
{
119+
useFactory: routerFactory,
120+
deps: CONST_EXPR([RouteRegistry, Location, ROUTER_PRIMARY_COMPONENT, ApplicationRef])
121+
})),
122122
CONST_EXPR(new Provider(
123123
ROUTER_PRIMARY_COMPONENT,
124124
{useFactory: routerPrimaryComponentFactory, deps: CONST_EXPR([ApplicationRef])}))
@@ -129,8 +129,10 @@ export const ROUTER_PROVIDERS: any[] = CONST_EXPR([
129129
*/
130130
export const ROUTER_BINDINGS = ROUTER_PROVIDERS;
131131

132-
function routerFactory(registry, location, primaryComponent) {
133-
return new RootRouter(registry, location, primaryComponent);
132+
function routerFactory(registry, location, primaryComponent, appRef) {
133+
var rootRouter = new RootRouter(registry, location, primaryComponent);
134+
appRef.registerDisposeListener(() => rootRouter.dispose());
135+
return rootRouter;
134136
}
135137

136138
function routerPrimaryComponentFactory(app) {

modules/angular2/src/router/router.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,12 +467,13 @@ export class Router {
467467
export class RootRouter extends Router {
468468
/** @internal */
469469
_location: Location;
470+
_locationSub: Object;
470471

471472
constructor(registry: RouteRegistry, location: Location, primaryComponent: Type) {
472473
super(registry, null, primaryComponent);
473474
this._location = location;
474-
this._location.subscribe((change) =>
475-
this.navigateByUrl(change['url'], isPresent(change['pop'])));
475+
this._locationSub = this._location.subscribe(
476+
(change) => this.navigateByUrl(change['url'], isPresent(change['pop'])));
476477
this.registry.configFromComponent(primaryComponent);
477478
this.navigateByUrl(location.path());
478479
}
@@ -489,6 +490,13 @@ export class RootRouter extends Router {
489490
}
490491
return promise;
491492
}
493+
494+
dispose(): void {
495+
if (isPresent(this._locationSub)) {
496+
ObservableWrapper.dispose(this._locationSub);
497+
this._locationSub = null;
498+
}
499+
}
492500
}
493501

494502
class ChildRouter extends Router {

modules/angular2/test/router/integration/router_integration_spec.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,17 @@ import {
3434

3535
import {LocationStrategy} from 'angular2/src/router/location_strategy';
3636
import {MockLocationStrategy} from 'angular2/src/mock/mock_location_strategy';
37+
import {ApplicationRef} from 'angular2/src/core/application_ref';
38+
import {MockApplicationRef} from 'angular2/src/mock/mock_application_ref';
3739

3840
export function main() {
3941
describe('router injectables', () => {
4042
beforeEachBindings(() => {
41-
return [ROUTER_PROVIDERS, provide(LocationStrategy, {useClass: MockLocationStrategy})];
43+
return [
44+
ROUTER_PROVIDERS,
45+
provide(LocationStrategy, {useClass: MockLocationStrategy}),
46+
provide(ApplicationRef, {useClass: MockApplicationRef})
47+
];
4248
});
4349

4450
// do not refactor out the `bootstrap` functionality. We still want to

0 commit comments

Comments
 (0)
X Tutup