2013-01-08 6 views
89

Ho un AuthService, che registra un utente, restituisce un oggetto json dell'utente. Quello che voglio fare è impostare quell'oggetto e avere tutte le modifiche riflesse sull'applicazione (stato di accesso/disconnessione) senza dover aggiornare la pagina.Come si memorizza un contesto utente corrente in Angolare?

Come potrei realizzare questo con AngularJS?

risposta

177

Il modo più semplice per eseguire questa operazione è utilizzare un servizio. Ad esempio:

app.factory('AuthService', function() { 
    var currentUser; 

    return { 
    login: function() { ... }, 
    logout: function() { ... }, 
    isLoggedIn: function() { ... }, 
    currentUser: function() { return currentUser; } 
    ... 
    }; 
}); 

È quindi possibile fare riferimento a questo in qualsiasi controller. Il codice seguente controlla le modifiche di un valore dal servizio (chiamando la funzione specificata) e quindi sincronizza i valori modificati nell'ambito.

app.controller('MainCtrl', function($scope, AuthService) { 
    $scope.$watch(AuthService.isLoggedIn, function (isLoggedIn) { 
    $scope.isLoggedIn = isLoggedIn; 
    $scope.currentUser = AuthService.currentUser(); 
    }); 
}); 

E quindi, naturalmente, è possibile utilizzare tali informazioni come meglio credi; per esempio. nelle direttive, nei modelli, ecc. È possibile ripetere questo (personalizzato per ciò che è necessario fare) nei controller dei menu, ecc. Sarà tutto aggiornato automaticamente quando si modifica lo stato del servizio.

Qualcosa di più specifico dipende dalla vostra implementazione.

Spero che questo aiuti!

+1

Questo è quello che stavo pensando anche io, ma sono curioso di sapere come funziona la fabbrica. Non otterremo un contesto correnteUser diverso ogni volta che viene creato un controller e richiede un AuthService? Forse non sono chiaro su come Angular si agganci. Idealmente avremmo un contesto. In alternativa pensavo di usare il negozio ngCookies (non la mia idea preferita) o lo spazio di archiviazione del browser (non ancora ben supportato). –

+28

@ChrisNicola In realtà, in AngularJS tutti i servizi sono singletons. Quindi il servizio viene creato la prima volta che viene richiesto (ad esempio da un controller o un altro servizio) e tutte le richieste successive restituiscono la stessa identica istanza. –

+0

@JoshDavidMiller Hai la proprietà 'isLoggedIn' come funzione? Non sarebbe un booleano? – nicholas

5

Vorrei modificare la buona risposta di Josh aggiungendo che, come un AuthService è in genere di interesse di chiunque (ad esempio, chiunque, ma la vista di accesso dovrebbe scomparire se nessuno è loggato), forse un'alternativa più semplice sarebbe quella di notificare gli interessati le parti che utilizzano $rootScope.$broadcast('loginStatusChanged', isLoggedIn); (1) (2), mentre le parti interessate (come i controller) ascoltavano utilizzando $scope.$on('loginStatusChanged', function (event, isLoggedIn) { $scope.isLoggedIn = isLoggedIn; }.

(1) $rootScope essere iniettato come un argomento del servizio

(2) Si noti che, nel caso probabile di un'operazione di login asincrona, ti consigliamo di notificare angolare che la trasmissione cambierà le cose, includendolo in una funzione $rootScope.$apply().

Ora, parlando di mantenere il contesto utente in tutti/molti i controller, potresti non essere felice di ascoltare le modifiche di accesso in ognuno di essi e preferirei ascoltare solo in un controller di accesso più in alto, quindi aggiungere altri login-aware controllori come bambini/controller incorporati di questo. In questo modo, il controller bambini sarà in grado di vedere le proprietà ereditate $ scope ereditate come il contesto dell'utente.

+4

Downvoted per spiegazione errata della funzione di fabbrica. Questo equivoco era già stato affrontato in [questo commento] (http://stackoverflow.com/questions/14206492/how-do-i-store-a-current-user-context-in-angular/14206567#comment20831205_14206567) mesi prima di te ha pubblicato la tua risposta. –

Problemi correlati