From 40eeaf5b37daeeacd0d612e086426c32de23967e Mon Sep 17 00:00:00 2001 From: Eric Vicenti Date: Tue, 21 Apr 2015 13:31:20 -0700 Subject: [PATCH] [ReactNative] Navigator contextual popToRoute and imperitive vs contextual docs --- .../CustomComponents/Navigator/Navigator.js | 84 ++++++++++++++----- 1 file changed, 64 insertions(+), 20 deletions(-) diff --git a/Libraries/CustomComponents/Navigator/Navigator.js b/Libraries/CustomComponents/Navigator/Navigator.js index 2d7a4a68f..f4fcdd443 100644 --- a/Libraries/CustomComponents/Navigator/Navigator.js +++ b/Libraries/CustomComponents/Navigator/Navigator.js @@ -135,11 +135,12 @@ var GESTURE_ACTIONS = [ * /> * ``` * - * ### Navigation Methods + * ### Navigator Methods * - * `Navigator` can be told to navigate in two ways. If you have a ref to - * the element, you can invoke several methods on it to trigger navigation: + * If you have a ref to the Navigator element, you can invoke several methods + * on it to trigger navigation: * + * - `getCurrentRoutes()` - returns the current list of routes * - `jumpBack()` - Jump backward without unmounting the current scene * - `jumpForward()` - Jump forward to the next scene in the route stack * - `jumpTo(route)` - Transition to an existing scene without unmounting @@ -156,18 +157,39 @@ var GESTURE_ACTIONS = [ * - `popToTop()` - Pop to the first scene in the stack, unmounting every * other scene * - * ### Navigator Object + * ### Navigation Context * - * The navigator object is made available to scenes through the `renderScene` - * function. The object has all of the navigation methods on it, as well as a - * few utilities: + * The navigator context object is made available to scenes through the + * `renderScene` function. Alternatively, any scene or component inside a + * Navigator can get the navigation context by calling + * `Navigator.getContext(this)`. * - * - `parentNavigator` - a refrence to the parent navigator object that was - * passed in through props.navigator - * - `onWillFocus` - used to pass a navigation focus event up to the parent - * navigator - * - `onDidFocus` - used to pass a navigation focus event up to the parent - * navigator + * Unlike the Navigator methods, the functions in navigation context do not + * directly control a specific navigator. Instead, the navigator context allows + * a scene to request navigation from its parents. Navigation requests will + * travel up through the hierarchy of Navigators, and will be resolved by the + * deepest active navigator. + * + * Navigation context objects contain the following: + * + * - `getCurrentRoutes()` - returns the routes for the closest navigator + * - `jumpBack()` - Jump backward without unmounting the current scene + * - `jumpForward()` - Jump forward to the next scene in the route stack + * - `jumpTo(route)` - Transition to an existing scene without unmounting + * - `parentNavigator` - a refrence to the parent navigation context + * - `push(route)` - Navigate forward to a new scene, squashing any scenes + * that you could `jumpForward` to + * - `pop()` - Transition back and unmount the current scene + * - `replace(route)` - Replace the current scene with a new route + * - `replaceAtIndex(route, index)` - Replace a scene as specified by an index + * - `replacePrevious(route)` - Replace the previous scene + * - `route` - The route that was used to render the scene with this context + * - `immediatelyResetRouteStack(routeStack)` - Reset every scene with an + * array of routes + * - `popToRoute(route)` - Pop to a particular scene, as specified by it's + * route. All scenes after it will be unmounted + * - `popToTop()` - Pop to the first scene in the stack, unmounting every + * other scene * */ var Navigator = React.createClass({ @@ -306,25 +328,30 @@ var Navigator = React.createClass({ this.parentNavigator = getNavigatorContext(this) || this.props.navigator; this._subRouteFocus = []; this.navigatorContext = { + // Actions for child navigators or interceptors: setHandlerForRoute: this.setHandlerForRoute, request: this.request, + // Contextual utilities parentNavigator: this.parentNavigator, getCurrentRoutes: this.getCurrentRoutes, + // `route` is injected by NavigatorStaticContextContainer - // Legacy, imperitive nav actions. Use request when possible. + // Contextual nav actions + pop: this.requestPop, + popToRoute: this.requestPopTo, + + // Legacy, imperitive nav actions. Will transition these to contextual actions jumpBack: this.jumpBack, jumpForward: this.jumpForward, jumpTo: this.jumpTo, push: this.push, - pop: this.pop, replace: this.replace, replaceAtIndex: this.replaceAtIndex, replacePrevious: this.replacePrevious, replacePreviousAndPop: this.replacePreviousAndPop, immediatelyResetRouteStack: this.immediatelyResetRouteStack, resetTo: this.resetTo, - popToRoute: this.popToRoute, popToTop: this.popToTop, }; this._handlers = {}; @@ -349,6 +376,14 @@ var Navigator = React.createClass({ return this._handleRequest.apply(null, arguments); }, + requestPop: function() { + return this.request('pop'); + }, + + requestPopTo: function(route) { + return this.request('pop', route); + }, + _handleRequest: function(action, arg1, arg2) { var childHandler = this._handlers[this.state.presentedIndex]; if (childHandler && childHandler(action, arg1, arg2)) { @@ -356,7 +391,7 @@ var Navigator = React.createClass({ } switch (action) { case 'pop': - return this._handlePop(); + return this._handlePop(arg1); case 'push': return this._handlePush(arg1); default: @@ -365,11 +400,20 @@ var Navigator = React.createClass({ } }, - _handlePop: function() { + _handlePop: function(route) { + if (route) { + var hasRoute = this.state.routeStack.indexOf(route) !== -1; + if (hasRoute) { + this.popToRoute(route); + return true; + } else { + return false; + } + } if (this.state.presentedIndex === 0) { return false; } - this._popN(1); + this.pop(); return true; }, @@ -904,7 +948,7 @@ var Navigator = React.createClass({ }, pop: function() { - return this.request('pop'); + this._popN(1); }, /**