fix(router): dynamic redirects

This commit is contained in:
Manu Mtz.-Almeida
2018-05-08 20:46:21 +02:00
parent bb809b63ed
commit ba551fda01
4 changed files with 44 additions and 39 deletions

View File

@@ -5114,6 +5114,7 @@ declare global {
namespace StencilComponents {
interface IonRouter {
'navChanged': (direction: RouterDirection) => Promise<boolean>;
'printDebug': () => void;
'push': (url: string, direction?: RouterDirection) => Promise<boolean>;
/**
* By default `ion-router` will match the routes at the root path ("/"). That can be changed when T

View File

@@ -150,6 +150,9 @@ By default, this property is `true`, change to `false` to allow hash-less URLs.
#### navChanged()
#### printDebug()
#### push()

View File

@@ -1,11 +1,14 @@
import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
import { Config, QueueController } from '../../interface';
import { debounce } from '../../utils/helpers';
import { printRedirects, printRoutes } from './utils/debug';
import { readNavState, waitUntilNavNode, writeNavState } from './utils/dom';
import { RouteChain, RouteRedirect, RouterDirection, RouterEventDetail } from './utils/interface';
import { routeRedirect, routerIDsToChain, routerPathToChain } from './utils/matching';
import { flattenRouterTree, readRedirects, readRoutes } from './utils/parser';
import { chainToPath, generatePath, parsePath, readPath, writePath } from './utils/path';
@Component({
tag: 'ion-router'
})
@@ -15,10 +18,8 @@ export class Router {
private previousPath: string|null = null;
private redirects: RouteRedirect[] = [];
private busy = false;
private init = false;
private state = 0;
private lastState = 0;
private timer: any;
@Element() el!: HTMLElement;
@@ -62,47 +63,15 @@ export class Router {
this.routes = flattenRouterTree(tree);
this.redirects = readRedirects(this.el);
this.win.addEventListener('ionRouteRedirectChanged', debounce(this.onRedirectChanged.bind(this), 10));
this.win.addEventListener('ionRouteDataChanged', debounce(this.onRoutesChanged.bind(this), 100));
const changed = await this.writeNavStateRoot(this.getPath(), RouterDirection.None);
if (!changed) {
console.error('[ion-router] did not change on will load');
}
}
componentDidLoad() {
this.init = true;
console.debug('[ion-router] router did load');
}
@Listen('ionRouteRedirectChanged')
protected onRedirectChanged(ev: CustomEvent) {
if (!this.init) {
return;
}
console.debug('[ion-router] redirect data changed', ev.target);
this.redirects = readRedirects(this.el);
}
@Listen('ionRouteDataChanged')
protected onRoutesChanged(ev: CustomEvent) {
if (!this.init) {
return;
}
console.debug('[ion-router] route data changed', ev.target, ev.detail);
// schedule write
if (this.timer) {
clearTimeout(this.timer);
this.timer = undefined;
}
this.timer = setTimeout(() => {
console.debug('[ion-router] data changed -> update nav');
const tree = readRoutes(this.el);
this.routes = flattenRouterTree(tree);
this.writeNavStateRoot(this.getPath(), RouterDirection.None);
this.timer = undefined;
}, 100);
}
@Listen('window:popstate')
protected onPopState() {
const direction = this.historyDirection();
@@ -111,6 +80,20 @@ export class Router {
return this.writeNavStateRoot(path, direction);
}
private onRedirectChanged() {
this.redirects = readRedirects(this.el);
const path = this.getPath();
if (path && routeRedirect(path, this.redirects)) {
this.writeNavStateRoot(path, RouterDirection.None);
}
}
private onRoutesChanged() {
const tree = readRoutes(this.el);
this.routes = flattenRouterTree(tree);
this.writeNavStateRoot(this.getPath(), RouterDirection.None);
}
private historyDirection() {
if (this.win.history.state === null) {
this.state++;
@@ -130,6 +113,14 @@ export class Router {
}
}
@Method()
printDebug() {
console.debug('CURRENT PATH', this.getPath());
console.debug('PREVIOUS PATH', this.previousPath);
printRoutes(this.routes);
printRedirects(this.redirects);
}
@Method()
async navChanged(direction: RouterDirection): Promise<boolean> {
if (this.busy) {

View File

@@ -1,8 +1,8 @@
import { RouteChain } from './interface';
import { RouteChain, RouteRedirect } from './interface';
import { generatePath } from './path';
export function printRoutes(routes: RouteChain[]) {
console.groupCollapsed(`[ion-core] registered ${routes.length} routes`);
console.group(`[ion-core] ROUTES[${routes.length}]`);
for (const chain of routes) {
const path: string[] = [];
chain.forEach(r => path.push(...r.path));
@@ -11,3 +11,13 @@ export function printRoutes(routes: RouteChain[]) {
}
console.groupEnd();
}
export function printRedirects(redirects: RouteRedirect[]) {
console.group(`[ion-core] REDIRECTS[${redirects.length}]`);
for (const redirect of redirects) {
if (redirect.to) {
console.debug('FROM: ', `$c ${generatePath(redirect.from)}`, 'font-weight: bold', ' TO: ', `$c ${generatePath(redirect.to)}`, 'font-weight: bold');
}
}
console.groupEnd();
}