Created
May 20, 2017 19:34
-
-
Save PaulBGD/dd80d09cbe53535c40ed72432ab9c982 to your computer and use it in GitHub Desktop.
Some sort of routing system in an MVP (this is just MP) pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Listener<T> = () => any; | |
type Canceller = () => void; | |
export interface Depends { | |
[key: string]: Model<any, any>; | |
} | |
abstract class Model<T, D extends Depends> { | |
private _listeners: Listener<T>[]; | |
private _cancel: Canceller[]; // from old code, is this supposed to do something? maybe unload all data from a specific page? | |
public loading: boolean; | |
public value: T | null; | |
constructor(private depends: D, initialState?: T, initialLoading?: boolean) { | |
this._listeners = []; | |
this.loading = initialLoading && true; | |
this.value = initialState === undefined ? null : initialState; | |
this._cancel = Object.keys(depends).map(key => depends[ key ].watch(() => this._update(depends))); | |
this._update(depends); // do initial update | |
} | |
protected abstract _update(data: D); | |
public update() { | |
this._update(this.depends); | |
} | |
public watch(listener: Listener<T>): () => void { | |
this._listeners.push(listener); | |
return () => this._listeners.splice(this._listeners.indexOf(listener), 1); | |
} | |
private dispatch() { | |
this._listeners.forEach(listener => listener()); | |
} | |
public set(value: T) { | |
const changed = value !== this.value; | |
this.value = value; | |
const oldLoading = this.loading; | |
this.loading = value === null; | |
if (changed || oldLoading !== this.loading) { | |
this.dispatch(); | |
} | |
} | |
public setLoading(loading: boolean) { | |
const changed = loading !== this.loading; | |
if (changed) { | |
this.loading = loading; | |
this.dispatch(); | |
} | |
} | |
} | |
export default Model; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Model, { Depends } from './Model'; | |
export interface Route<D> { | |
data: D; | |
scene: SvelteComponent; | |
} | |
interface RouteData { | |
stack: Route<any>[]; | |
index: number; | |
} | |
type RouteDepends = Depends; | |
class RouteModel extends Model<RouteData, RouteDepends> { | |
constructor() { | |
super({}, { | |
stack: [], | |
index: -1, | |
}, false); | |
} | |
protected _update(data: Depends) { | |
// nothing to do | |
} | |
} | |
export default new RouteModel(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import routeModel, { Route } from '../models/RouteModel'; | |
export function getCurrentRoute(): Route<any> { | |
const { stack, index } = routeModel.value; | |
if (index >= 0) { | |
return stack[index]; | |
} | |
throw new Error('No routes yet.'); | |
} | |
export function pop() { | |
const { stack, index } = routeModel.value; | |
routeModel.set({ stack, index: Math.max(0, index - 1) }); | |
} | |
export function popToTop() { | |
const { stack } = routeModel.value; | |
routeModel.set({ stack, index: 0 }); | |
} | |
export function push(route: Route<any>) { | |
const { stack, index } = routeModel.value; | |
stack.splice(index + 1); | |
stack.push(route); | |
routeModel.set({ stack, index: index + 1 }); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment