feat(router): add location service
This commit is contained in:
58
modules/angular2/src/mock/location_mock.js
vendored
Normal file
58
modules/angular2/src/mock/location_mock.js
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
import {SpyObject, proxy} from 'angular2/test_lib';
|
||||
|
||||
import {isBlank, isPresent, IMPLEMENTS} from 'angular2/src/facade/lang';
|
||||
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
||||
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {Location} from 'angular2/src/router/location';
|
||||
|
||||
|
||||
@proxy
|
||||
@IMPLEMENTS(Location)
|
||||
export class DummyLocation extends SpyObject {
|
||||
urlChanges:List<string>;
|
||||
_path:string;
|
||||
_subject:EventEmitter;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._path = '/';
|
||||
this.urlChanges = ListWrapper.create();
|
||||
this._subject = new EventEmitter();
|
||||
}
|
||||
|
||||
setInitialPath(url:string) {
|
||||
this._path = url;
|
||||
}
|
||||
|
||||
path():string {
|
||||
return this._path;
|
||||
}
|
||||
|
||||
simulateUrlPop(pathname:string) {
|
||||
ObservableWrapper.callNext(this._subject, {
|
||||
'url': pathname
|
||||
});
|
||||
}
|
||||
|
||||
go(url:string) {
|
||||
if (this._path === url) {
|
||||
return;
|
||||
}
|
||||
this._path = url;
|
||||
ListWrapper.push(this.urlChanges, url);
|
||||
}
|
||||
|
||||
forward() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
back() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
subscribe(onNext, onThrow = null, onReturn = null) {
|
||||
ObservableWrapper.subscribe(this._subject, onNext, onThrow, onReturn);
|
||||
}
|
||||
|
||||
noSuchMethod(m){return super.noSuchMethod(m);}
|
||||
}
|
40
modules/angular2/src/router/location.js
vendored
Normal file
40
modules/angular2/src/router/location.js
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
import {global} from 'angular2/src/facade/lang';
|
||||
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
||||
|
||||
export class Location {
|
||||
_location;
|
||||
_subject:EventEmitter;
|
||||
_history;
|
||||
constructor() {
|
||||
this._subject = new EventEmitter();
|
||||
this._location = global.location;
|
||||
this._history = global.history;
|
||||
global.addEventListener('popstate', (_) => this._onPopState(_), false);
|
||||
}
|
||||
|
||||
_onPopState(_) {
|
||||
ObservableWrapper.callNext(this._subject, {
|
||||
'url': this._location.pathname
|
||||
});
|
||||
}
|
||||
|
||||
path() {
|
||||
return this._location.pathname;
|
||||
}
|
||||
|
||||
go(url:string) {
|
||||
this._history.pushState(null, null, url);
|
||||
}
|
||||
|
||||
forward() {
|
||||
this._history.forward();
|
||||
}
|
||||
|
||||
back() {
|
||||
this._history.back()
|
||||
}
|
||||
|
||||
subscribe(onNext, onThrow = null, onReturn = null) {
|
||||
ObservableWrapper.subscribe(this._subject, onNext, onThrow, onReturn);
|
||||
}
|
||||
}
|
20
modules/angular2/src/router/router.js
vendored
20
modules/angular2/src/router/router.js
vendored
@ -6,6 +6,7 @@ import {RouteRegistry} from './route_registry';
|
||||
import {Pipeline} from './pipeline';
|
||||
import {Instruction} from './instruction';
|
||||
import {RouterOutlet} from './router_outlet';
|
||||
import {Location} from './location';
|
||||
|
||||
/**
|
||||
* # Router
|
||||
@ -28,17 +29,21 @@ export class Router {
|
||||
_outlets:Map<any, RouterOutlet>;
|
||||
_children:Map<any, Router>;
|
||||
_subject:EventEmitter;
|
||||
|
||||
constructor(registry:RouteRegistry, pipeline:Pipeline, parent:Router = null, name = '/') {
|
||||
_location:Location;
|
||||
|
||||
constructor(registry:RouteRegistry, pipeline:Pipeline, location:Location, parent:Router = null, name = '/') {
|
||||
this.name = name;
|
||||
this.navigating = false;
|
||||
this.parent = parent;
|
||||
this.previousUrl = null;
|
||||
this._outlets = MapWrapper.create();
|
||||
this._children = MapWrapper.create();
|
||||
this._location = location;
|
||||
this._registry = registry;
|
||||
this._pipeline = pipeline;
|
||||
this._subject = new EventEmitter();
|
||||
this._location.subscribe((url) => this.navigate(url));
|
||||
this.navigate(location.path());
|
||||
}
|
||||
|
||||
|
||||
@ -97,6 +102,9 @@ export class Router {
|
||||
this._startNavigating();
|
||||
|
||||
var result = this._pipeline.process(instruction)
|
||||
.then((_) => {
|
||||
this._location.go(instruction.matchedUrl);
|
||||
})
|
||||
.then((_) => {
|
||||
ObservableWrapper.callNext(this._subject, instruction.matchedUrl);
|
||||
})
|
||||
@ -170,19 +178,19 @@ export class Router {
|
||||
}
|
||||
|
||||
static getRoot():Router {
|
||||
return new RootRouter(new Pipeline());
|
||||
return new RootRouter(new Pipeline(), new Location());
|
||||
}
|
||||
}
|
||||
|
||||
export class RootRouter extends Router {
|
||||
constructor(pipeline:Pipeline) {
|
||||
super(new RouteRegistry(), pipeline, null, '/');
|
||||
constructor(pipeline:Pipeline, location:Location) {
|
||||
super(new RouteRegistry(), pipeline, location, null, '/');
|
||||
}
|
||||
}
|
||||
|
||||
class ChildRouter extends Router {
|
||||
constructor(parent, name) {
|
||||
super(parent._registry, parent._pipeline, parent, name);
|
||||
super(parent._registry, parent._pipeline, parent._location, parent, name);
|
||||
this.parent = parent;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user