138 lines
24 KiB
JavaScript
Raw Normal View History

import { ReflectiveInjector } from '@angular/core';
import { RouterOutletMap } from './router_outlet_map';
import { recognize } from './recognize';
import { rootNode } from './utils/tree';
import { createEmptyUrlTree } from './url_tree';
import { PRIMARY_OUTLET } from './shared';
import { createEmptyState, ActivatedRoute } from './router_state';
import { createUrlTree } from './create_url_tree';
import { forEach } from './utils/collection';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/toPromise';
import { fromPromise } from 'rxjs/observable/fromPromise';
import { forkJoin } from 'rxjs/observable/forkJoin';
export class Router {
constructor(rootComponent, resolver, urlSerializer, outletMap, location) {
this.rootComponent = rootComponent;
this.resolver = resolver;
this.urlSerializer = urlSerializer;
this.outletMap = outletMap;
this.location = location;
this.currentUrlTree = createEmptyUrlTree();
this.currentRouterState = createEmptyState(rootComponent.constructor);
this.setUpLocationChangeListener();
this.navigateByUrl(this.location.path());
}
get routerState() {
return this.currentRouterState;
}
get urlTree() {
return this.currentUrlTree;
}
navigateByUrl(url) {
const urlTree = this.urlSerializer.parse(url);
return this.runNavigate(urlTree, false);
}
resetConfig(config) {
this.config = config;
}
dispose() { this.locationSubscription.unsubscribe(); }
createUrlTree(commands, { relativeTo, queryParameters, fragment } = {}) {
const a = relativeTo ? relativeTo : this.routerState.root;
return createUrlTree(a, this.currentUrlTree, commands, queryParameters, fragment);
}
navigate(commands, extras = {}) {
return this.runNavigate(this.createUrlTree(commands, extras));
}
serializeUrl(url) { return this.urlSerializer.serialize(url); }
parseUrl(url) { return this.urlSerializer.parse(url); }
setUpLocationChangeListener() {
this.locationSubscription = this.location.subscribe((change) => {
this.runNavigate(this.urlSerializer.parse(change['url']), change['pop']);
});
}
runNavigate(url, pop) {
const r = recognize(this.config, url, this.currentRouterState).mergeMap((newState) => {
return new ActivateRoutes(this.resolver, newState, this.currentRouterState).activate(this.outletMap).map(() => {
this.currentUrlTree = url;
this.currentRouterState = newState;
if (!pop) {
this.location.go(this.urlSerializer.serialize(url));
}
});
});
r.subscribe((a) => { }, (e) => { }, () => { });
return r;
}
}
class ActivateRoutes {
constructor(resolver, futureState, currState) {
this.resolver = resolver;
this.futureState = futureState;
this.currState = currState;
}
activate(parentOutletMap) {
const currRoot = this.currState ? rootNode(this.currState) : null;
const futureRoot = rootNode(this.futureState);
return this.activateChildRoutes(futureRoot, currRoot, parentOutletMap);
}
activateChildRoutes(futureNode, currNode, outletMap) {
const prevChildren = nodeChildrenAsMap(currNode);
const observables = [];
futureNode.children.forEach(c => {
observables.push(this.activateRoutes(c, prevChildren[c.value.outlet], outletMap).toPromise());
delete prevChildren[c.value.outlet];
});
forEach(prevChildren, (v, k) => this.deactivateOutletAndItChildren(outletMap._outlets[k]));
return forkJoin(observables);
}
activateRoutes(futureNode, currNode, parentOutletMap) {
const future = futureNode.value;
const curr = currNode ? currNode.value : null;
const outlet = getOutlet(parentOutletMap, futureNode.value);
if (future === curr) {
return this.activateChildRoutes(futureNode, currNode, outlet.outletMap);
}
else {
this.deactivateOutletAndItChildren(outlet);
const outletMap = new RouterOutletMap();
return this.activateNewRoutes(outletMap, future, outlet).mergeMap(() => this.activateChildRoutes(futureNode, currNode, outletMap));
}
}
activateNewRoutes(outletMap, future, outlet) {
const resolved = ReflectiveInjector.resolve([
{ provide: ActivatedRoute, useValue: future },
{ provide: RouterOutletMap, useValue: outletMap }
]);
return fromPromise(this.resolver.resolveComponent(future.component)).
map(factory => outlet.activate(factory, resolved, outletMap));
}
deactivateOutletAndItChildren(outlet) {
if (outlet && outlet.isActivated) {
forEach(outlet.outletMap._outlets, (v, k) => this.deactivateOutletAndItChildren(v));
outlet.deactivate();
}
}
}
function nodeChildrenAsMap(node) {
return node ?
node.children.reduce((m, c) => {
m[c.value.outlet] = c;
return m;
}, {}) :
{};
}
function getOutlet(outletMap, route) {
let outlet = outletMap._outlets[route.outlet];
if (!outlet) {
if (route.outlet === PRIMARY_OUTLET) {
throw new Error(`Cannot find primary outlet`);
}
else {
throw new Error(`Cannot find the outlet ${route.outlet}`);
}
}
return outlet;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3JvdXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiT0FBTyxFQUFxQixrQkFBa0IsRUFBRSxNQUFNLGVBQWU7T0FHOUQsRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUI7T0FDOUMsRUFBRSxTQUFTLEVBQUUsTUFBTSxhQUFhO09BQ2hDLEVBQUUsUUFBUSxFQUFZLE1BQU0sY0FBYztPQUMxQyxFQUFXLGtCQUFrQixFQUFFLE1BQU0sWUFBWTtPQUNqRCxFQUFFLGNBQWMsRUFBVSxNQUFNLFVBQVU7T0FDMUMsRUFBRSxnQkFBZ0IsRUFBZSxjQUFjLEVBQUMsTUFBTSxnQkFBZ0I7T0FHdEUsRUFBRSxhQUFhLEVBQUUsTUFBTSxtQkFBbUI7T0FDMUMsRUFBRSxPQUFPLEVBQUUsTUFBTSxvQkFBb0I7T0FHckMsdUJBQXVCO09BQ3ZCLDRCQUE0QjtPQUM1Qiw2QkFBNkI7T0FDN0IsRUFBQyxXQUFXLEVBQUMsTUFBTSw2QkFBNkI7T0FDaEQsRUFBQyxRQUFRLEVBQUMsTUFBTSwwQkFBMEI7QUFPakQ7SUFTRSxZQUFvQixhQUFvQixFQUFVLFFBQTJCLEVBQVUsYUFBNEIsRUFBVSxTQUEwQixFQUFVLFFBQWtCO1FBQS9KLGtCQUFhLEdBQWIsYUFBYSxDQUFPO1FBQVUsYUFBUSxHQUFSLFFBQVEsQ0FBbUI7UUFBVSxrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUFVLGNBQVMsR0FBVCxTQUFTLENBQWlCO1FBQVUsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNqTCxJQUFJLENBQUMsY0FBYyxHQUFHLGtCQUFrQixFQUFFLENBQUM7UUFDM0MsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGdCQUFnQixDQUFNLGFBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMzRSxJQUFJLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztRQUNuQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMs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