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 {RouterOutlet} from './directives/router_outlet';
import {Type, isBlank, isPresent} from 'angular2/src/facade/lang'; import {Type, isBlank, isPresent} from 'angular2/src/facade/lang';
import {ListWrapper} from 'angular2/src/facade/collection'; 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 {StringMapWrapper} from 'angular2/src/facade/collection';
import {BaseException} from 'angular2/src/facade/exceptions'; import {BaseException} from 'angular2/src/facade/exceptions';
import {RouterUrlSerializer} from './router_url_serializer'; import {RouterUrlSerializer} from './router_url_serializer';
@ -33,13 +38,14 @@ export class RouterOutletMap {
export class Router { export class Router {
private _prevTree: Tree<RouteSegment>; private _prevTree: Tree<RouteSegment>;
private _urlTree: Tree<UrlSegment>; private _urlTree: Tree<UrlSegment>;
private _locationSubscription: any;
private _changes: EventEmitter<void> = new EventEmitter<void>(); private _changes: EventEmitter<void> = new EventEmitter<void>();
constructor(private _rootComponent: Object, private _rootComponentType: Type, constructor(private _rootComponent: Object, private _rootComponentType: Type,
private _componentResolver: ComponentResolver, private _componentResolver: ComponentResolver,
private _urlSerializer: RouterUrlSerializer, private _urlSerializer: RouterUrlSerializer,
private _routerOutletMap: RouterOutletMap, private _location: Location) { private _routerOutletMap: RouterOutletMap, private _location: Location) {
this._setUpLocationChangeListener();
this.navigateByUrl(this._location.path()); this.navigateByUrl(this._location.path());
} }
@ -53,6 +59,13 @@ export class Router {
return this._navigate(this.createUrlTree(changes, segment)); 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> { private _navigate(url: Tree<UrlSegment>): Promise<void> {
this._urlTree = url; this._urlTree = url;
return recognize(this._componentResolver, this._rootComponentType, 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."); throw new BaseException("Bootstrap at least one component before injecting Router.");
} }
// TODO: vsavkin this should not be null // TODO: vsavkin this should not be null
return new Router(null, app.componentTypes[0], componentResolver, urlSerializer, routerOutletMap, let router = new Router(null, app.componentTypes[0], componentResolver, urlSerializer,
location); routerOutletMap, location);
app.registerDisposeListener(() => router.dispose());
return router;
} }

View File

@ -64,6 +64,19 @@ export function main() {
expect(location.path()).toEqual('/team/33/simple'); 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', it('should support nested routes',
fakeAsync(inject([Router, TestComponentBuilder], (router, tcb) => { fakeAsync(inject([Router, TestComponentBuilder], (router, tcb) => {
let fixture = tcb.createFakeAsync(RootCmp); let fixture = tcb.createFakeAsync(RootCmp);

View File

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