start example change angularjs angular-ui-router

angularjs - example - ui-router params



¿Cómo accedo a la propiedad ''resolver'' de un estado raíz de UI-Router desde $ stateChangeStart? (5)

Estoy tratando de implementar un sistema de verificación de acceso de usuarios y verificación de acceso en mi aplicación, sin embargo, sigo golpeando obstáculos. Creo que lo tengo de la manera correcta esta vez, pero tengo un último obstáculo.

Un poco de historia: intenté poner todo el código en $ rootScope.on ($ startChangeStart) y funcionó, horriblemente ... pero funcionó. La ruta siempre fue redirigida, pero debido a la verificación de autenticación en el backend, se mostró la primera página de solicitud por 1/2 un segundo y luego la página de redireccionamiento cada vez. Por lo tanto, intenté "pausar" la carga de la página llamando a evt.preventDefault () justo al inicio de la función $ startChangeStart, que funcionó, pero al intentar volver al usuario a la ruta original, causó un bucle infinito en el enrutador.

Entonces, después de investigar más y leer muchas publicaciones en la pila, estoy seguro de que ''resolver:'' es el lugar adecuado para poner la comprobación de autenticación para garantizar que la página no se carga mientras ocurre, y luego redirigir al usuario si es necesario desde $ startChangeStart. ($ estado y evento siempre están indefinidos en mis intentos de inyectarlos en una función de resolución) Parece la combinación ganadora.

Mi problema: tengo la resolución sobre el estado raíz en mi aplicación: ''main''

Esto fue para evitar la redundancia de código, sin embargo, no puedo determinar cómo acceder a las propiedades del estado raíz y, por lo tanto, el resultado de la resolución, desde la función $ stateChangeStart. El estado toState es el estado secundario, mientras que el estado fromState es el estado anterior o un estado abstracto con la ruta ''^'' ...

¿Tengo que poner la resolución en cada estado secundario para que esto funcione, o hay una manera de acceder al estado raíz desde este punto?

Configuración básica de la aplicación:

angular.module(''App'', [''ui.router'', ''ui.bootstrap'', ''ui.event'', ''AngularGM'', ''ngResource'']) .config([''$urlRouterProvider'', ''$stateProvider'', function($urlRouterProvider, $stateProvider){ $urlRouterProvider .when(''/home'', ''/'') .when('''', ''/'') .when(''/sign-up/joe'', ''/sign-up'') .otherwise(''/''); $stateProvider .state(''main'', { url: '''', abstract: true, templateUrl: ''views/main.html'', controller: ''MainCtrl'', resolve: { checkAccess: [''accountService'', function(accountService) { accountService.checkAuth(function(){ accountService.checkAccess(function (access){ return access; }); }); }] } }) .state(''main.home'', { url: '''', abstract: true, templateUrl: ''views/home.html'', controller: ''HomeCtrl'' }) .state(''main.home.index'', { url: ''/'', templateUrl: ''views/home/index.html'' }); .run([''$rootScope'', ''$state'', ''$stateParams'', ''accountService'', function ($rootScope, $state, $stateParams) { $rootScope.$state = $state; $rootScope.$stateParams = $stateParams; $rootScope.$on(''$stateChangeStart'', function(event, toState, toParams, fromState, fromParams) { console.dir(toState); console.dir(toParams); console.dir(fromState); console.dir(fromParams); if (!toState.checkAccess.allowed) { event.preventDefault(); $state.transitionTo(toState.checkAccess.newState); } }); }]);

Esta es la salida de las llamadas de console.dir () en los dos objetos de estado:

Object name: "main.home.index" templateUrl: "views/home/index.html" url: "/" __proto__: Object Object controller: "PlacesCtrl" name: "main.places.search" templateUrl: "views/places.html" url: "/places" __proto__: Object

Actualizar

Vaya, olvidé mencionar que la versión de AngularJS es v1.2.0-rc.2

$ state.current console.dir ()

Object abstract: true name: "" url: "^" views: null __proto__: Object


¿Es posible hacer la redirección desde su servicio de cuenta? Si detecta que el usuario falla en sus funciones checkAuth o checkAccess, podría evitar que la devolución de llamada se ejecute y redirigir al usuario a su página de error (o inicio de sesión).

Otra cosa a considerar es implementar algún tipo de variable / cola de estados si desea redirigir a alguien a la página de inicio de sesión para actualizar su autorización / autenticación y luego volver al estado anterior.


Esta respuesta es muy tarde pero puede ser útil.

Las resoluciones de un estado y el evento $stateChangeStart se ejecutan al mismo tiempo. Cuando intente acceder a los datos resueltos en $stateChangeStart , no estará disponible, pero estará disponible cuando se $stateChangeSuccess evento $stateChangeSuccess .

Si usa $stateChangeStart entonces deberá hacer checkAuth desde el evento $stateChangeStart de dos lugares y la resolución principal. Como tienen una ejecución paralela, se enviarán al servidor al menos 2 solicitudes de red para los mismos datos.

En su lugar, use $stateChangeSuccess . El uso de esto asegurará que sus resoluciones se resuelvan y luego podrá verificar el acceso. Además, en lugar de acceder a las propiedades resueltas, acceda a los datos resueltos utilizando el servicio angular.


No necesitas usar la resolve . Echa un vistazo a mi solución:

app.run ($rootScope, $state, Auth, ngDialog) -> $rootScope.$on ''$stateChangeStart'', (e, to) -> if to.authRequired and not Auth.isAuthenticated() e.preventDefault() Auth.currentUser().then( (user) -> $state.go(to) (failure) -> $rootScope.storedState = to $state.go(''main'') ngDialog.closeAll() ngDialog.open template: ''modals/login.html'' controller: ''loginCtrl'' className: ''ngdialog-theme-default'' )

Utilizo angular_devise y ngDialog pero son opcionales y puedes implementarlo con el servicio de tu propio usuario.


Sí, creo que puedes acceder al estado raíz desde la función $stateChangeStart .

Cuando utilizo AngularJS puro, normalmente uso current.$$route

Por ejemplo, utilizando la siguiente ruta.

.when(''/home'', { title:''Home'', bodyClass: ''meetings'', controler: ''HomeCtrl'' })

Puedo acceder al estado raíz como tal

$rootScope.$on(''$routeChangeSuccess'', function (event, current, previous) { if (current.$$route) { $rootScope.title = current.$$route.title; $rootScope.bodyClass = current.$$route.bodyClass; } });

Usar ui-router es un poco diferente, ya que se llama $state.current . Y puede acceder a todas las propiedades asociadas a cualquier ruta que toque (por ejemplo: $ state.current.url)

Así que en tu código podrías tener algo como esto

.run([''$rootScope'', ''$state'', ''$stateParams'', function ($rootScope, $state, $stateParams) { $rootScope.$on(''$stateChangeStart'', function(event, toState, toParams, fromState, fromParams) { console.log($state.current.url); }); }]);


Si inicializa su estado con un objeto vacío predeterminado en la resolución, podrá manipularlo dentro de $stateChangeStart .

$stateProvider .state ''home'', url: "/" resolve: {} ... $rootScope.$on ''$stateChangeStart'', (e, toState, toParams, fromState, fromParams) -> toState.resolve.x = -> $timeout -> alert "done" , 3000

Consulte https://github.com/angular-ui/ui-router/issues/1165