feat(router): listen to location changes

Closes #8362
This commit is contained in:
vsavkin 2016-04-30 11:57:02 -07:00 committed by Victor Savkin
parent 76d6f5fa0d
commit 62a0809e81
4 changed files with 33 additions and 5 deletions

View File

@ -2,7 +2,12 @@ import {OnInit, provide, ReflectiveInjector, ComponentResolver} from 'angular2/c
import {RouterOutlet} from './directives/router_outlet';
import {Type, isBlank, isPresent} from 'angular2/src/facade/lang';
import {ListWrapper} from 'angular2/src/facade/collection';
import {EventEmitter, Observable, PromiseWrapper} from 'angular2/src/facade/async';
import {
EventEmitter,
Observable,
PromiseWrapper,
ObservableWrapper
} from 'angular2/src/facade/async';
import {StringMapWrapper} from 'angular2/src/facade/collection';
import {BaseException} from 'angular2/src/facade/exceptions';
import {RouterUrlSerializer} from './router_url_serializer';
@ -33,13 +38,14 @@ export class RouterOutletMap {
export class Router {
private _prevTree: Tree<RouteSegment>;
private _urlTree: Tree<UrlSegment>;
private _locationSubscription: any;
private _changes: EventEmitter<void> = new EventEmitter<void>();
constructor(private _rootComponent: Object, private _rootComponentType: Type,
private _componentResolver: ComponentResolver,
private _urlSerializer: RouterUrlSerializer,
private _routerOutletMap: RouterOutletMap, private _location: Location) {
this._setUpLocationChangeListener();
this.navigateByUrl(this._location.path());
}
@ -53,6 +59,13 @@ export class Router {
return this._navigate(this.createUrlTree(changes, segment));
}
dispose(): void { ObservableWrapper.dispose(this._locationSubscription); }
private _setUpLocationChangeListener(): void {
this._locationSubscription = this._location.subscribe(
(change) => { this._navigate(this._urlSerializer.parse(change['url'])); });
}
private _navigate(url: Tree<UrlSegment>): Promise<void> {
this._urlTree = url;
return recognize(this._componentResolver, this._rootComponentType, url)

View File

@ -24,6 +24,8 @@ function routerFactory(app: ApplicationRef, componentResolver: ComponentResolver
throw new BaseException("Bootstrap at least one component before injecting Router.");
}
// TODO: vsavkin this should not be null
return new Router(null, app.componentTypes[0], componentResolver, urlSerializer, routerOutletMap,
location);
let router = new Router(null, app.componentTypes[0], componentResolver, urlSerializer,
routerOutletMap, location);
app.registerDisposeListener(() => router.dispose());
return router;
}

View File

@ -64,6 +64,19 @@ export function main() {
expect(location.path()).toEqual('/team/33/simple');
})));
it('should navigate when locations changes',
fakeAsync(inject([Router, TestComponentBuilder, Location], (router, tcb, location) => {
let fixture = tcb.createFakeAsync(RootCmp);
router.navigateByUrl('/team/22/user/victor');
advance(fixture);
location.simulateHashChange("/team/22/user/fedor");
advance(fixture);
expect(fixture.debugElement.nativeElement).toHaveText('team 22 { hello fedor, aux: }');
})));
it('should support nested routes',
fakeAsync(inject([Router, TestComponentBuilder], (router, tcb) => {
let fixture = tcb.createFakeAsync(RootCmp);

View File

@ -7,7 +7,7 @@ import {
ROUTER_PROVIDERS,
OnActivate,
RouteSegment,
Tree
Tree,
} from 'angular2/alt_router';
import * as db from './data';
import {Location} from 'angular2/platform/common';