¿Cómo diferir la definición de rutas en Angular.js?

He configurado algunas rutas básicas que están disponibles para todos los usuarios antes de que inicien sesión:

App.config(function ($routeProvider) { $routeProvider. when('/login', { templateUrl: 'views/login.html', controller: PageStartCtrl.Controller }). otherwise({ redirectTo: '/login' }); }); 

Entonces, lo único que puede hacer el usuario es iniciar sesión. Después de que el usuario inicie sesión, me gustaría registrar rutas adicionales como esta:

 $http .post('api/Users/Login', { User: userName, Password: userPassword }) .success(function (response : any) { App.config(function ($routeProvider) { $routeProvider .when('/dashboard', { templateUrl: 'part/dashboard.html', controller: DashboardCtrl.Controller }); }); 

Sin embargo, supongo que debería llamar al método .config solo una vez, porque $ routeProvider es una instancia completamente nueva que no sabe nada sobre / login route. La depuración adicional me mostró que la primera instancia de $ resourceProvider se usa al resolver el cambio de vista.

P: ¿Hay alguna forma de registrar rutas más tarde?

La solución de Agregar rutas y plantillas dinámicamente a $ routeProvider podría funcionar, pero es bastante fea (variable global involucrada nastyGlobalReferenceToRouteProvider ).

Como las rutas se definen en un nivel de proveedor, normalmente las nuevas rutas solo se pueden definir en el bloque de configuración. El problema es que en el bloque de configuración, todos los servicios vitales aún no están definidos (más notablemente, $http ). Entonces, en la superficie, parece que w no puede definir rutas dinámicamente.

Ahora, resulta que en la práctica es bastante fácil agregar / eliminar rutas en cualquier punto del ciclo de vida de la aplicación. Mirando el código fuente $route podemos ver que toda la definición de rutas se mantiene simplemente en el hash $route.routes que se puede modificar en cualquier momento como ese (ejemplo simplificado):

 myApp.controller('MyCtrl', function($scope, $route) { $scope.defineRoute = function() { $route.routes['/dynamic'] = {templateUrl: 'dynamic.tpl.html'}; }; }); 

Aquí está el jsFiddle que demuestra esto en acción: http://jsfiddle.net/4zwdf/6/

En realidad, si queremos estar cerca de lo que AngularJS está haciendo, la lógica de definición de ruta debería ser un poco más compleja ya que AngularJS también está definiendo una ruta de redireccionamiento para manejar correctamente las rutas con / al final (hacerlo efectivamente opcional).

Entonces, aunque la técnica anterior funcionará, debemos tener en cuenta lo siguiente:

  • Esta técnica depende de la implementación interna y podría romperse si el equipo de AngularJS decide cambiar la forma en que se definen / coinciden las rutas .
  • También es posible definir la ruta de otherwise usando $route.routes ya que la ruta predeterminada se almacena en el mismo hash bajo la tecla null

Descubrí que la respuesta de @ pkozlowski.opensource solo funciona en angularjs 1.0.1. Sin embargo, después de que angular-route.js se convierte en un archivo independiente en la versión posterior, establecer directamente $ route no funciona.

Después de revisar el código, encuentro que la clave de $ route.routes ya no se usa para hacer coincidir la ubicación, pero se usa $ route.route [key] .RegExp. Después de copiar el origen cuando y la función pathRegExp, la ruta funciona. Ver jsfiddle: http://jsfiddle.net/5FUQa/1/

  function addRoute(path, route) { //slightly modified 'when' function in angular-route.js } addRoute('/dynamic', { templateUrl: 'dynamic.tpl.html' });