2015-04-02 11 views
9

Sto provando ad aggiungere gli stati alla mia app in modo dinamico e ho provato ad usare ui-router. Ho provato a seguire questo thread. AngularJS - UI-router - How to configure dynamic views

Nel mio caso, ci sono alcuni stati existant già e ho bisogno di aggiungere a tale elenco con gli stati dinamici vengano letti da JSON

Per qualche motivo, ottengo l'errore iniettore $ urlRouterProvider quando si cerca di utilizzare per il metodo deferIntercept(). Nel mio caso, sto usando angular 1.3 e la versione ui-router è 0.2.10. Vedo che è possibile creare stati in modo sinergico. Ma possiamo aggiungere alla lista esistente di stati già configurate staticamente

Ecco il mio codice ogni aiuto è apprezzato,

MY modules.json,

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

miei 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; 

}]);

+0

A che punto durante il processo di esecuzione di applicazione Stai cercando di creare o spingere in un nuovo stato? se è la funzione di post-esecuzione ... non sono sicuro che sia possibile non senza estendere l'oggetto $ stato con un metodo impostato. Sono abbastanza sicuro che è possibile creare un nuovo stato solo tramite lo StateProvider all'interno della funzione di configurazione. – btm1

+0

sto aggiungendo gli stati in config e quindi associando gli stati al provider di stato nella funzione di esecuzione stessa – looneytunes

risposta

11

C'è a working plunker, con tutti i frammenti di cui sopra.

Nel caso in cui vogliamo aggiungere alcuni Stati, che non sono già esistenti, dovremmo controllare il $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(); 

    }); 

Controllare che here in action

+0

Grazie a @Radim Kohler ... Sono riuscito a caricare gli stati in modo dinamico. Ma per fare riferimento ai controller dagli stati dinamici. Come si farebbe? – looneytunes

+0

I controller dagli stati dinamici devono essere già caricati ... a meno che non usiamo alcuni strumenti o tecniche come caricarli pigramente, quando vengono toccati per la prima volta. Qui, ho creato plunker e fornito una descrizione dettagliata per mostrare come farlo con * RequireJS * http: //stackoverflow.com/q/22627806/1679310 ... Spero che aiuti un po '... –