2015-04-02 14 views
9

Próbuję dynamicznie dodawać stany do mojej aplikacji i próbowałem używać ui-routera. Próbowałem śledzić ten wątek. AngularJS - UI-router - How to configure dynamic views

W moim przypadku, istnieją już pewne istnial stany i muszę dołączyć do tej listy ze stanów dynamicznych są odczytywane z json

Z jakiegoś powodu otrzymuję błąd wtryskiwacza na $ urlRouterProvider podczas próby użycia dla metody deferIntercept(). W moim przypadku używam kąta 1.3, a wersja routera to 0.2.10. Widzę, że możesz tworzyć stany w sposób synonimiczny. Ale możemy dodać do istniejącej listy państw już skonfigurowane statycznie

Tu jest mój kod Każda pomoc jest mile widziana,

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" 
    }] 
}] 

Moi 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

W jakim momencie procesu uruchamiania aplikacji starasz się stworzyć lub wcisnąć nowy stan? jeśli jest to funkcja post-run ... nie jestem pewien, czy nie jest to możliwe bez rozszerzenia obiektu stanu $ o ustaloną metodę. Jestem prawie pewien, że możesz utworzyć nowy stan tylko za pomocą funkcji stateProvider w funkcji konfiguracyjnej. – btm1

+0

Dodaję stany w config, a następnie dołączam stany do dostawcy stanu w samej funkcji run – looneytunes

Odpowiedz

11

Istnieje a working plunker, ze wszystkimi powyższymi fragmentami.

W przypadku, gdy chcemy dodać niektórych państwach, które nie są już istniejące, powinniśmy sprawdzić $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(); 

    }); 

Sprawdź, here in action

+0

Dzięki @Radim Kohler ... Udało mi się załadować stany dynamicznie. Ale w odniesieniu do kontrolerów ze stanów dynamicznych. Jak by to zrobić? – looneytunes

+0

Kontrolery ze stanów dynamicznych muszą być już załadowane ... chyba że użyjemy jakichś narzędzi lub technik, aby wczytać je leniwie, po pierwszym dotknięciu. Tutaj stworzyłem plunkera i podałem szczegółowy opis, aby pokazać, jak to zrobić za pomocą * RequireJS * http: //stackoverflow.com/q/22627806/1679310 ... Mam nadzieję, że trochę pomaga ... –