stateprovider stateparams sref angularjs angular-ui angular-ui-router

angularjs - stateparams - UI-Router angular, accediendo al estado padre y redirigiendo dinĂ¡micamente al usuario a un determinado estado secundario



ui router nested views (3)

El parpadeo se debe al hecho de que en realidad está permitiendo que el usuario acceda a http://myapp/validate antes de moverlo a la ruta correcta.
Puede evitar esto al redirigirlo a la ruta correcta sin mostrar la ruta principal.

app.run(function($rootScope){ $rootScope.$on(''$stateChangeStart'', function(e, toState, toParams, fromState, fromParams), { if(toState.name === ''validate'') { // some conditional e.preventDefault(); // This tells the app not to move to the validate route if (HasPermission.get(''can-lock-as-admin'')) { $state.go(''validate.lock-as-admin''); } if (HasPermission.get(''can-lock-as-clerk'')) { $state.go(''validate.lock-as-clerk''); } } }); }); });

Para tener una solución aún más limpia probablemente puedas usar un bloque de resolve que verifique el permiso, pero no estoy al 100% sobre esto y no tengo tiempo para comprobarlo ahora.
Le sugiero que eche un vistazo a este artículo, ya que explica en buena manera escenarios similares.

Tengo un estado principal al que se accede accediendo a la URL http://myapp/validate .

Al llegar a esta URL, dentro del controlador realizo una verificación de permiso y redirijo al usuario a uno de los dos estados secundarios.

Esto funciona, 80% satisfecho, pero usa algunos recursos y causa un pequeño parpadeo en mi aplicación, ya que básicamente cargo una vista que NO UTILIZO.

¿Hay una mejor manera de lograr esto?

¿Algunas ideas?

angular.module(''app.validate'').config([''$stateProvider'', function($stateProvider) { $stateProvider .state(''validate'', { url: ''/validate'', template: ''<ui-view/>'', controller: [''$state'', ''HasPermission'', function ($state, HasPermission) { // Here is where I do my logic. if (HasPermission.get(''can-lock-as-admin'')) { $state.go(''validate.lock-as-admin''); } if (HasPermission.get(''can-lock-as-clerk'')) { $state.go(''validate.lock-as-clerk''); } }] }) .state(''validate.lock-as-admin'', { templateUrl: ''theUrl'', controller: ''ValidateLockAdminCtrl'' }) .state(''validate.lock-as-clerk'', { templateUrl: ''theUrl'', controller: ''ValidateLockClerkCtrl'' }) .state(''validate.commit'', { templateUrl: ''theUrl'', controller: ''ValidateCommitCtrl'' }); }]);


Puede usar algún atributo de permiso personalizado en las rutas, que puede verificar, como:

.state(''validate.lock-as-admin'', { template: ''<h1>lock as admin</h1>'', permission: ''admin'', otherwise: ''validate.lock-as-clert'' }) .state(''validate.lock-as-clerk'', { template: ''<h1>lock as clerk</h1>'', permission: ''clerk'', otherwise: ''validate.lock-as-admin'' })

Luego podría ver los cambios de ruta y hacer alguna verificación de permiso personalizada. Aquí hay un ejemplo de cómo se podría lograr esto. ejemplo


Si no desea extender ui-router , le aconsejaría lo siguiente:

  • No crear estados de transición.

    El motor ui-router opera bajo la suposición de que cuando se dirige a un estado y la transición es exitosa, se debe mostrar la vista del estado. Por lo tanto, si dirige a un estado y permite que se resuelva mientras intenta hacer la transición a otro lugar, prepárese para el parpadeo.

    Esto lleva a la pregunta "¿Qué pasa si no dejo que el estado resuelva y en su lugar redirija?" . Desafortunadamente, parece que hay algunos problemas con la redirección en medio de la resolución del estado. Vea la parte de la respuesta después del descanso.

  • O crea retrocesos ...

    En lugar de tener un estado de transición por separado, puede decidir cuál de los subestados es el predeterminado y directo a ese. Allí puede realizar sus controles y posiblemente redirigir a otro lugar. Esto seguirá provocando parpadeo en caso de redirección. Pero si su valor predeterminado es bien elegido y la redirección ocurre ocasionalmente, es un buen comienzo.

  • ... o directamente a los destinos correctos.

    Usar la máquina de estado correctamente significa dirigirse a los estados en los que realmente desea que vaya el usuario. Esto significa que cualquier comprobación debe realizarse antes de activar las transiciones de estado. Por supuesto, esto solo es posible cuando se dirige programáticamente. Aún necesita la estrategia anterior de "recuperación" para tratar con el usuario que intenta comenzar en un estado específico ingresando su URL.

Alternativamente, podría extender el ui-router un poco para permitir transiciones de estado durante la resolución del estado. (La última vez que verifiqué, no se pudo redirigir de forma segura a un estado diferente de una resolve ). Por ejemplo, podría decorar $state y detener los intentos de redirección mientras la resolución de estado ya está en progreso (se puede ver observando los eventos apropiados) y luego, redirija al último estado capturado después de que se complete la resolución del estado. Si lo hace, puede crear estados de transición como este:

.state(''someTransitionalState'', { resolve: { redirect: [''permissions'', ''$state'', ''$q'', function (permissions, $state, $q) { $state.go(permissions.has(...) ? ... : ...); return $q.reject(''transitional state - redirected elsewhere''); }] } })

De esta forma, el estado de transición nunca se resolverá y todos los intentos de alcanzarlo resultarán en llegar a los otros destinos seleccionados.