2014-10-01 18 views
7

Sto utilizzando ui.router per il routing nella mia app Angolare. Esiste uno scenario di accesso tipico, in cui sto reindirizzando un utente all'URL di accesso se non è connesso. Senza la libreria ui.router, questo ha funzionato correttamente utilizzando $ routeChangeStart evento combinato con $location.path. Ora, sto usando l'evento $stateChangeStart, combinato con $state.go e il nulla funziona! Invia anche il mio browser in un ciclo infinito. Ho letto da altre fonti che si tratta di un bug noto e nessuna delle soluzioni suggerite funziona per me. Inoltre, anche $location.path non reindirizza alla pagina di accesso.Router angolare ui - Il reindirizzamento non funziona affatto

Ecco come ho configurato i miei sentieri:

.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) { 
    $stateProvider 
     .state('main', { 
      url: '/', 
      templateUrl: 'views/main.html', 
      controller: 'MainCtrl' 
     }) 
     .state('about', { 
      url: '/about', 
      templateUrl: 'views/about.html', 
      controller: 'AboutCtrl' 
     }) 
     .state('login', { 
      url: '/login', 
      templateUrl: 'views/loginform.html', 
      controller: 'LoginCtrl' 
     }); 
    $urlRouterProvider.otherwise("/"); 
}]) 

e la mia run metodo:

.run(['$state', '$rootScope', '$location', function($state, $rootScope, $location) { 
    //Check when routing starts 
    //event, next, current 
    $rootScope.$on('$stateChangeStart', function(e, toState, toParams, fromState, fromParams) { 
     //Redirect to login if the user is not logged in 
     if (!isUserLoggedIn) { 

      //Some suggestion 
      //e.preventDefault(); 
      console.log('Not logged in'); 

      //Infinite loop, kills my browser! 
      $state.go('login'); 
      $state.transitionTo('login'); 

      //Some suggestion 
      $state.go('login', { url: '/login'}); 

      //Doesn't work 
      $location.path('/login'); 

      //$location.path($state.href('login'); 
      console.log('Redirected'); 
     } 
    }); 
+1

Dove è definito 'isUserLoggedIn'? – Phil

+0

Ho un servizio di autenticazione, l'ho saltato da questo codice per alcuni motivi ufficiali. Ha funzionato bene con il routing predefinito. –

risposta

8

Cosa avremmo bisogno qui, è quello di NON reindirizzare, se lo stato è TO già il 'login'.

Solo un aggiustamento redatto sarebbe

$rootScope.$on('$stateChangeStart', function(e, toState , toParams 
               , fromState, fromParams) { 

    var isLogin = toState.name === "login"; 

    if(isLogin){ 

     return; // no need to redirect anymore 
    } 
    ... 

E inoltre, dovremmo chiamare $state.go('login'); con la event.preventDefault();

... 
// also prevent default on redirect 
$state.go('login'); 
event.preventDefault(); 
... 

Si prega di controllare questo Q & Un How can I fix 'Maximum call stack size exceeded' AngularJS E a plunker con una soluzione simile

+0

Ma il mio flag di accesso è in realtà una funzione che restituisce un valore booleano e fa parte di alcuni servizi. Come lo uso in questa situazione? Inoltre, il ciclo infinito non comparirà ovunque? –

+0

Puoi controllare questa risposta: http://stackoverflow.com/a/24725180/1679310? e prova questo plunker http://plnkr.co/edit/JLABnz?p=preview? Dovrebbe mostrare come potrebbe funzionare. Esiste anche un servizio Extern 'User' che restituisce booleano, ma la logica if/where to redirect è ancora valutata in $ stateChangeStart. questo aiuta? –

+0

Ottimo! 'preventDefault' funziona nel gestore di eventi e ora il reindirizzamento alla pagina di login funziona correttamente. Ma, nella mia funzione di disconnessione, utilizzo $ state.go per il reindirizzamento alla pagina di accesso, ma porta ancora a un ciclo. Il logout è attivato da un clic del pulsante quindi posso usare preventDefault. –

1

Ho usato qualcosa di simile a questo:

MyApp.run(['$rootScope', '$state', function ($rootScope, $state) { 
    // The event 
    $rootScope.$on('$stateChangeStart', function (e, toState, toParams, fromState, fromParams) { 
    // Is user already logged in? 
    var isUserLoggedIn = $rootScope.isUserLoggedIn(); 

    if (isUserLoggedIn) { 
     // don't let user visit login state, he's already logged in. 
     $state.go('home'); 
     // preventDefault as described in @radim's answer 
     e.preventDefault(); 
    } else if (toState.name === "login") { 
     // user is not logged in and is not going to login state right now, send him there first. 
     $state.go('login'); 
     // preventDefault as described in @radim's answer 
     e.preventDefault(); 
    } 
    }); 
}]); 
Problemi correlati