Angular - UI Router - programmatically adds states

Is there a way to programmatically add states to $ stateProvider after module configuration, for example. service?

To add more context to this question, I have a situation where I can go with two approaches:

  • try forcibly reloading the state defined in the module configuration, the problem is that the reloadOnSearch state is set to false , so when I try $ state. go ('state.name', {new: param}, {reload: true}); nothing happens, any ideas?

State determination

.state('index.resource.view', { url: "/:resourceName/view?pageNumber&pageSize&orderBy&search", templateUrl: "/resourceAdministration/views/view.html", controller: "resourceViewCtrl", reloadOnSearch: false, }) 
  1. try programmatically adding the states that I need to load from the service so that routing can work correctly. I would rather go with the first option, if possible.
+52
javascript angularjs angular-services angular-ui-router
Sep 16 '14 at 10:28
source share
3 answers

See -edit- for updated information.

Normal states are added to $stateProvider during the configuration phase. If you want to add states at runtime, you need to save the link to $stateProvider .

This code has not been verified, but should do what you want. It creates a service called runtimeStates . You can enter it at runtime, and then add states.

 // config-time dependencies can be injected here at .provider() declaration myapp.provider('runtimeStates', function runtimeStates($stateProvider) { // runtime dependencies for the service can be injected here, at the provider.$get() function. this.$get = function($q, $timeout, $state) { // for example return { addState: function(name, state) { $stateProvider.state(name, state); } } } }); 

I implemented some things called Future States in Additional Features of the UI-Router that take care of some of the corner cases for you, like displaying URLs in states that don't exist yet. Future states also show how lazy you are to download source code for runtime states. Take a look at the source code to understand what is related to it.

-edit- for UI-Router 1.0 +

In UI-Router 1.0, states can be registered and logged into the account at runtime using StateRegistry.register and StateRegistry.deregister .

To access StateRegistry, enter it $stateRegistry or enter $uiRouter and access it through UIRouter.stateRegistry .

UI-Router 1.0 also includes Future States out of the box, which handles lazy loading of state definitions, even syncing to a URL.

+106
Sep 16 '14 at 15:31
source share

Chris T nailed it! The supplier is the way to go. You do not need to hit it on the window object, save, protect, etc.

Cross-referencing his answer with this article really helped: http://blog.xebia.com/2013/09/01/differences-between-providers-in-angularjs/#provider

The solution makes certain $ stateProvider modules during the configuration block available to other modules during their execution blocks.

In my situation, I dynamically create dashboard states based on user rights.

In my configuration block, my provider is configured by passing the stateProvider module (to access it later).

 //in dashboard.module.js var dashboardModule = angular.module('app.modules.dashboard',[ 'app.modules.dashboard.controllers', 'app.modules.dashboard.services', 'app.modules.dashboard.presentations.mileage' ]) .provider('$dashboardState', function($stateProvider){ this.$get = function(PATHS, $state){ return { addState: function(title, controllerAs, templatePrefix) { $stateProvider.state('dashboard.' + title, { url: '/' + title, views: { 'dashboardModule@dashboard': { templateUrl: PATHS.DASHBOARD + (templatePrefix ? templatePrefix + '/' : '/') + title + '/' + title + '.view.html', controller: controllerAs ? controllerAs : null } } }); } } } }); 

This will make my Dashboard state provider available to other modules instead of patting it on the window.

Then, in my User module launcher (controller), I can access the state provider of the control panel and dynamically inject the states.

 var UserControllers = angular.module('app.modules.user.controllers', []) .controller("UserLoginController", ["$state", "$dashboardState", function($state, $dashboardState){ $dashboardState.addState('faq', null, 'content'); $state.go('dashboard.faq'); }]); 
+13
Jul 17 '15 at 15:08
source share

Yes, it’s possible, but because they involve caching layers. Alex Feinberg posted the solution on his blog here:

http://alexfeinberg.wordpress.com/2014/03/08/dynamically-populating-angular-ui-router-states-from-a-service/

The end of the article includes an example of creating state using stateProvider:

 app.stateProvider.state(ent.lob.name.toLowerCase(), { url: '/' + ent.lob.name.toLowerCase(), controller: ent.lob.name.toLowerCase() + 'Controller', templateUrl: 'lobs/views/' + ent.lob.name.toLowerCase() + '.html' }); 
+4
Sep 16 '14 at 15:31
source share



All Articles