/** * @author Ed Spencer * @private * * The Router is an ordered set of route definitions that decode a url into a controller function to execute. Each * route defines a type of url to match, along with the controller function to call if it is matched. The Router is * usually managed exclusively by an {@link Ext.app.Application Application}, which also uses a * {@link Ext.app.History History} instance to find out when the browser's url has changed. * * Routes are almost always defined inside a {@link Ext.app.Controller Controller}, as opposed to on the Router itself. * End-developers should not usually need to interact directly with the Router as the Application and Controller * classes manage everything automatically. See the {@link Ext.app.Controller Controller documentation} for more * information on specifying routes. */ Ext.define('Ext.app.Router', { requires: ['Ext.app.Route'], config: { /** * @cfg {Array} routes The set of routes contained within this Router. * @readonly */ routes: [], /** * @cfg {Object} defaults Default configuration options for each Route connected to this Router. */ defaults: { action: 'index' } }, constructor: function(config) { this.initConfig(config); }, /** * Connects a url-based route to a controller/action pair plus additional params. * @param {String} url The url to recognize. * @param {Object} [params] Additional parameters. */ connect: function(url, params) { params = Ext.apply({url: url}, params || {}, this.getDefaults()); var route = Ext.create('Ext.app.Route', params); this.getRoutes().push(route); return route; }, /** * Recognizes a url string connected to the Router, return the controller/action pair plus any additional * config associated with it. * @param {String} url The url to recognize. * @return {Object/undefined} If the url was recognized, the controller and action to call, else `undefined`. */ recognize: function(url) { var routes = this.getRoutes(), length = routes.length, i, result; for (i = 0; i < length; i++) { result = routes[i].recognize(url); if (result !== undefined) { return result; } } return undefined; }, /** * Convenience method which just calls the supplied function with the Router instance. Example usage: * * Ext.Router.draw(function(map) { * map.connect('activate/:token', {controller: 'users', action: 'activate'}); * map.connect('home', {controller: 'index', action: 'home'}); * }); * * @param {Function} fn The fn to call */ draw: function(fn) { fn.call(this, this); }, /** * @private */ clear: function() { this.setRoutes([]); } }, function() { //<deprecated product=touch since=2.0> /** * Restores compatibility for the old `Ext.Router.draw` syntax. This needs to be here because apps often include * _routes.js_ just after _app.js_, so this is our only opportunity to hook this in. There is a small piece of code * inside Application's {@link Ext.app.Application#onDependenciesLoaded onDependenciesLoaded} that sets up the other end of this. * @singleton * @private */ Ext.Router = {}; var drawStack = []; /** * Application's {@link Ext.app.Application#onDependenciesLoaded onDependenciesLoaded} has a deprecated-wrapped line that calls this. Basic idea is that once an * app has been instantiated we set that at Ext.Router's `appInstance` and then redirect any calls to * {@link Ext.app.Router#draw Ext.Router.draw} to that app's Router. We keep a `drawStack` above so that we can call {@link Ext.app.Router#draw Ext.Router.draw} one or * more times before the application is even instantiated and it will simply link it up once everything is * present. */ Ext.Router.setAppInstance = function(app) { Ext.Router.appInstance = app; if (drawStack.length > 0) { Ext.each(drawStack, Ext.Router.draw); } }; Ext.Router.draw = function(mapperFn) { Ext.Logger.deprecate( 'Ext.Router.map is deprecated, please define your routes inline inside each Controller. ' + 'Please see the 1.x -> 2.x migration guide for more details.' ); var app = Ext.Router.appInstance, router; if (app) { router = app.getRouter(); mapperFn(router); } else { drawStack.push(mapperFn); } }; //</deprecated> });