can we add dynamic states to $stateprovider with a

2019-01-11 11:57发布

问题:

I am trying to add states to my app dynamically and tried using ui-router. I tried following this thread. AngularJS - UI-router - How to configure dynamic views

In my case, there are some existant states already and i need to append to that list with the dynamic states being read from json

For some reason, i get injector error on $urlRouterProvider when trying to use for deferIntercept() method. In my case, i am using angular 1.3 and the ui-router version is 0.2.10. I see that you can create states synamically. But can we add to the existing list of states already configured statically

Here is my code any help is appreciated,

MY modules.json,

 [{
   "name": "applications1",
    "url": "^/templates/applications1",
    "parent": "authenticated",
    "abstract": false,
     "views": [{
     "name": "",
     "templateUrl": "html/templates/basicLayout.html"
   }, {
      "name": "header@applications1",
      "templateUrl": "html/templates/header.html"
  }],
   {
   "name": "login",
   "url": "/login",
   "abstract": false,
   "views": [{
     "name": "",
     "templateUrl": "html/admin/loginForm.html"
   }]
 }]

My app.js

       var $stateProviderRef = null;
       var $urlRouterProviderRef = null;

       var aModule = angular.module('App', [
             'ui.bootstrap','ui.router'   
       ]);


         adminModule.run(['$rootScope', '$state', '$stateParams',
              function ($rootScope, $state, $stateParams) {
              $rootScope.$state = $state;
          $rootScope.$stateParams = $stateParams;
         }])

         adminModule.run(['$q', '$rootScope','$http', '$urlRouter',
            function ($q, $rootScope, $http, $urlRouter) 
            {
      $http
          .get("modules.json")
          .success(function(data)
       {
           angular.forEach(data, function (value, key) 
       { 
        var state = {
        "url": value.url,
        "parent" : value.parent,
        "abstract": value.abstract,
        "views": {}
      };

      angular.forEach(value.views, function (view) 
      {
        state.views[view.name] = {
          templateUrl : view.templateUrl,
        };
      });

      $stateProviderRef.state(value.name, state);
    });
    // Configures $urlRouter's listener *after* your custom listener

    $urlRouter.sync();
    $urlRouter.listen();
  });
}]);

    aModule.config(['$locationProvider', '$stateProvider',        '$urlRouterProvider', '$httpProvider', function ($locationProvider, $stateProvider, $urlRouterProvider, $httpProvider) {

    // XSRF token naming
    $httpProvider.defaults.xsrfHeaderName = 'x-dt-csrf-header';
    $httpProvider.defaults.xsrfCookieName = 'X-CSRF-TOKEN';

$httpProvider.interceptors.push('httpInterceptor');

$stateProvider
    .state('login', {
        url: '/login',
        templateUrl: 'html/XXX/loginForm.html',
        controller: 'AController'
    })
    .state('sAgree', {
        url: '/serviceAgreement',
        templateUrl: 'html/xxx/s.html',
        controller: 'SController'
    });
   $urlRouterProvider.deferIntercept();

$urlRouterProvider.otherwise('/login');

$locationProvider.html5Mode({enabled: false});
$stateProviderRef = $stateProvider;
$urlRouterProviderRef = $urlRouterProvider;

}]);

回答1:

There is a working plunker, with all the above snippets.

In case that we want add some states, which are not already existing, we should check the $state.get('stateName')

$http
  .get("modules.json")
  .success(function(data) {
    angular.forEach(data, function(value, key) {

      // here we ask if there is a state with the same name
      var getExistingState = $state.get(value.name)

      // no need to continue, there is state (e.g. login) already
      if(getExistingState !== null){
        return; 
      }

      var state = {
        "url": value.url,
        "parent": value.parent,
        "abstract": value.abstract,
        "views": {}
      };

      angular.forEach(value.views, function(view) {
        state.views[view.name] = {
          templateUrl: view.templateUrl,
        };
      });

      $stateProviderRef.state(value.name, state);
    });
    // Configures $urlRouter's listener *after* your custom listener

    $urlRouter.sync();
    $urlRouter.listen();

  });

Check that here in action