diff --git a/Actions.js b/Actions.js new file mode 100644 index 000000000..030b10c38 --- /dev/null +++ b/Actions.js @@ -0,0 +1,90 @@ +import Route from './Route'; +import Router from './Router'; + +function isNumeric(n){ + return !isNaN(parseFloat(n)) && isFinite(n); +} + +function filterParam(data){ + if (data.toString()!='[object Object]') + return data; + if (!data){ + return; + } + var proto = (data||{}).constructor.name; + // avoid passing React Native parameters + if (proto != 'Object'){ + data = {}; + } + if (data.data){ + data.data = filterParam(data.data); + } + return data; +} + +class Actions { + currentRouter: ?Router; + + constructor(){ + this.pop = this.pop.bind(this); + this.route = this.route.bind(this); + } + + route(name: string, props: { [key: string]: any} = {}){ + if (!this.currentRouter){ + throw new Error("No current router is set"); + } + if (props.toString()!='[object Object]') + props = {data : props}; + + props = filterParam(props); + // check if route is in children, current or parent routers + let router: Router = this.currentRouter; + // deep into child router + while (router.currentRoute.childRouter){ + router = router.currentRoute.childRouter; + } + while (!router.routes[name]){ + const route = router.parentRoute; + if (!route || !route.parent){ + throw new Error("Cannot find router for route="+name); + } + router = route.parent; + } + if (router.route(name, props)){ + this.currentRouter = router; + return true; + } + return false; + } + pop(num: number = 1){ + if (!isNumeric(num)){ + num = 1; + } + if (!this.currentRouter){ + throw new Error("No current router is set"); + } + if (num > 1){ + for (let i=0;i: + + + + : + React.cloneElement(React.Children.only(this.route.children), {...this.route.props, data:this.props, route:this.route}); + return child; + } + + getName(){ + return this.route.name; + } + + getTitle() { + return this.route.title || ""; + } + + getBackButtonTitle(navigator, index, state){ + let previousIndex = index - 1; + let previousRoute = state.routeStack[previousIndex]; + let title = previousRoute.getTitle(navigator, previousIndex, state); + return title.length>10 ? null : title; + } + + renderRightButton() { + if (this.route.onRight && this.route.rightTitle){ + return ( this.route.onRight({...this.route.props, ...this.props})} + style={[ExNavigator.Styles.barRightButton, this.route.rightButtonStyle]}> + {this.route.rightTitle} + ); + } else { + return null; + } + } +} + +const defaultCreateRoute = function(route, data){ + return new ExRoute(route, data); +}; + +export default class ExRouter extends React.Component { + router: Router; + + constructor(props){ + super(props); + this.onPop = this.onPop.bind(this); + this.onPush = this.onPush.bind(this); + this.onPop = this.onPop.bind(this); + this.onPush = this.onPush.bind(this); + this.onReplace = this.onReplace.bind(this); + this.onJump = this.onJump.bind(this); + } + + onPush(route: Route, props:{ [key: string]: any}):boolean { + if (this.props.onPush){ + const res = this.props.onPush(route, props); + if (!res){ + return false; + } + } + this.refs.nav.push(new ExRoute(route, props)); + return true; + } + + onReplace(route: Route, props:{ [key: string]: any}):boolean { + if (this.props.onReplace){ + const res = this.props.onReplace(route, props); + if (!res){ + return false; + } + } + this.refs.nav.replace(new ExRoute(route, props)); + return true; + } + + onJump(route: Route, props:{ [key: string]: any}):boolean { + if (this.props.onJump){ + const res = this.props.onJump(route, props); + if (!res){ + return false; + } + } + const navigator = this.refs.nav; + const routes = navigator.getCurrentRoutes(); + const exist = routes.filter(el=>el.getName()==route.name); + if (exist.length){ + navigator.jumpTo(exist[0]); + } else { + navigator.push(new ExRoute(route, props)); + + } + this.setState({selected: route.name}); + return true; + } + + onPop(num: number){ + if (this.props.onPop){ + const res = this.props.onPop(num); + if (!res){ + return false; + } + } + this.refs.nav.pop(); + return true; + } + + render() { + const router = this.props.router; + if (!router){ + throw new Error("No router is defined"); + } + const Header = this.props.header; + const header = Header ?
: null; + + const Footer = this.props.footer; + const footer = Footer ?