import * as b from "bobril"; import * as f from "fun-model"; import * as cm from "./component"; import * as c from "./common"; export interface IRouteComponentState extends f.IState { } export interface IRouteData { parentRouteName?: string; routeParams: b.Params; } export interface IRouteComponentContext extends cm.IContext { data: TData; lastData: TData; } export function createRouteComponent(component: b.IBobrilComponent) : (cursor: f.ICursor | c.CursorFieldsMap) => b.IComponentFactory { return (innerCursor: f.ICursor | c.CursorFieldsMap) => b.createDerivedComponent( b.createVirtualComponent({ init(ctx: IRouteComponentContext) { ctx.forceShouldChange = false; if (c.isCursor(innerCursor)) { ctx.cursor = innerCursor; ctx.state = f.getState(ctx.cursor); } else { Object.keys(innerCursor).forEach(ck => { (ctx)[c.unifyCursorName(ck)] = (>innerCursor)[ck]; (ctx)[c.unifyStateName(ck)] = f.getState((>innerCursor)[ck]); }); } ctx.lastData = ctx.data; }, shouldChange(ctx: IRouteComponentContext): boolean { let shouldChange = ctx.forceShouldChange; if (c.isCursor(innerCursor)) { let previousState = ctx.state; ctx.state = f.getState(ctx.cursor); shouldChange = ctx.state !== previousState; } else { Object.keys(innerCursor).forEach(ck => { const stateName = c.unifyStateName(ck); const previousState = (ctx)[stateName]; (ctx)[stateName] = f.getState((>innerCursor)[ck]); shouldChange = shouldChange || (ctx)[stateName] !== previousState; }); } let previousData = ctx.lastData; ctx.lastData = ctx.data; return shouldChange || (ctx.data !== previousData); } }), component); }