2013-10-05 8 views
11

Sto imparando proprio Angular e sto tentando di creare un'app che limiti l'accesso al contenuto basato sull'autenticazione. Ho la parte di autenticazione funzionante (utilizzando anche il framework PHP di Laravel), ma sto riscontrando un problema nel "ricaricare" determinati contenuti in base allo stato di autenticazione, vale a dire dopo un'autenticazione corretta.AngularJS: Ricarica ng-include dopo l'autenticazione dell'utente (o un modo migliore per risolvere il problema)

Inizialmente, quello che sto cercando di fare è aggiornare il menu di navigazione principale dopo che un utente effettua il login. Sono sicuro che c'è un approccio migliore, ma quello che ho finora è una vista restituita dal server che ha una navigazione diversa elementi a seconda che l'utente abbia effettuato l'accesso o meno, quindi caricandolo in un elemento con ng-include.

Esiste un'opzione per accedere, che carica un modulo di accesso nella vista di ng. Dopo che l'utente ha effettuato l'accesso, vorrei aggiornare il ng-include con la vista dal server.

C'è un modo per ricaricare quel modello nel ng-include dopo un login riuscito?

Per favore sentiti libero di raccomandare una tecnica migliore per risolvere questo se questo è l'approccio sbagliato. Certo, sarebbe molto facile farlo in jQuery, ma preferirei fare le cose in modo angolare.

Ecco alcuni del mio codice finora:

index.html:

<div class="container" ng-controller="appController"> 

    <div id="nav" ng-include src="menuUrl()"></div> 

    <div class="row"> 
     <div class="span3" ng-include src="'partials/brands.html'" ng-controller="brandController"></div> 
     <div class="span9" ng-view></div> 
    </div> 

</div> 

Alcuni controller:

.controller('appController', function($scope){ 
    $scope.loggedIn = false; 

    $scope.menuUrl = function() { 
     return "partials/nav.html"; 
    }; 

}) 
.controller('loginController',function($scope, $sanitize, $location, Authenticate, Flash){ 
    $scope.login = function(){ 
     Authenticate.save({ 
      'email': $sanitize($scope.email), 
      'password': $sanitize($scope.password) 
     },function() { 
      $location.path('/products') 
      Flash.clear() 
      sessionStorage.authenticated = true; 
     },function(response){ 
      Flash.show(response.flash) 
     }) 
    } 
}) 
.controller('logoutController',function($scope, $location, Authenticate, Flash){ 
    $scope.logout = function(){ 
     Authenticate.get({},function(response){ 
      delete sessionStorage.authenticated 
      Flash.show(response.flash) 
      $location.path('/login') 
     }) 
    } 
}) 

Servizi:

.factory('Authenticate', function($resource){ 
    return $resource("/service/authenticate/") 
}) 
.factory('Flash', function($rootScope){ 
    return { 
     show: function(message){ 
      $rootScope.flash = message 
     }, 
     clear: function(){ 
      $rootScope.flash = "" 
     } 
    } 
}) 

App:

012 vista
.config(['$routeProvider',function($routeProvider){ 
     $routeProvider.when('/', { 
      templateUrl: 'partials/home.html', 
      controller: 'homeController' 
     }) 

     $routeProvider.when('/login', { 
      templateUrl: 'partials/login.html', 
      controller: 'loginController' 
     }) 

     $routeProvider.when('/logout', { 
      templateUrl: 'partials/logout.html', 
      controller: 'logoutController' 
     }) 

     $routeProvider.otherwise({redirectTo :'/'}) 
    }]) 
    .config(function($httpProvider){ 

     var interceptor = function($rootScope,$location,$q,Flash){ 

     var success = function(response){ 
      return response 
     } 

     var error = function(response){ 
      if (response.status == 401){ 
       delete sessionStorage.authenticated 
       $location.path('/') 
       Flash.show(response.data.flash) 

      } 
      return $q.reject(response) 

     } 
      return function(promise){ 
       return promise.then(success, error) 
      } 
     } 
     $httpProvider.responseInterceptors.push(interceptor) 
    }) 
    .run(function($http,CSRF_TOKEN){ 
     $http.defaults.headers.common['csrf_token'] = CSRF_TOKEN; 
    }) 

laravel:

<ul class="nav nav-tabs"> 
    <li><a href="#/">Home...</a></li> 
    @if(!Auth::check()) 
    <li><a href="#/login">Log-in</a></li> 
    @else 
    <li><a href="#/logout">Log-out</a></li> 
    @endif 
    <li><input name="search" id="search" type="search" placeholder="Search products..." /> 
</ul> 

risposta

12

Si può iniziare con l'innalzamento di un evento quando il login utente è successo sul rootscope utilizzando il metodo di trasmissione

$rootScope.$broadcast('userLoggedIn',{user:user}); 

Sulla appController è possibile iscriversi alla persino

$scope.$on("userLoggedIn",function(event,args) { 
    $scope.menuUrl=null; 
    $scope.menuUrl="partials/nav.html"; 
}); 

implica anche che cambi il menuUrl in una proprietà nel tuo controller e nel binding html.

Alos, se è possibile definire più visualizzazioni server per l'accesso e l'utente anonimo, è possibile semplicemente capovolgere la vista sul login utente.

+0

che è stato proprio quello che stavo cercando di capire, grazie. Quello che inizialmente avevo intenzione di fare era "ricaricare" il partial (che viene emesso dal server), ma sembra che siano in cache in Angular e in realtà ho dovuto fornire un altro partial (lo stesso partial con un percorso diverso sul server) a caricare per lo stato di accesso/uscita. Questa è una supposizione corretta? In ogni caso, grazie mille. Risposta molto succinta – Jazzy

+0

Bene come penso ora, l'approccio null potrebbe non funzionare come hai detto che i partial sono stati memorizzati nella cache. Avere parziali diversi sarebbe meglio. Un altro modo in cui posso pensare sarebbe generare il menu sul lato client usando dati json e qualche tipo di 'ng-repeat'. In questo caso, fare 'null' e riassegnare il partial causerebbe il rerendering della vista che richiederebbe nuovamente dati json dal server. – Chandermani

9

risposta @Chandermani s' è quasi vicino, infatti, si può semplicemente aggiungere alcuni params casuali per forzare l'aggiornamento, proprio come questo:

app.controller('appController', function($scope){ 
    var getMenu = function(){ 
    var random = Math.random(); 
    return "partials/nav.html?r=" + random; 
    } 
    $scope.menuUrl = getMenu(); 
    $scope.$on('userLoggedIn', function(){ 
    $scope.menuUrl = getMenu(); 
    }) 
}) 
+1

Non è una cattiva idea. – Jazzy

+1

Era intelligente. Grazie ! – Serguzest

+3

Tranne che non funziona se si inseriscono i modelli nella cache dei modelli – Serguzest

Problemi correlati