Как сохранить текущий контекст пользователя в Angular?

У меня есть AuthService, который регистрируется у пользователя, он возвращает обратно пользовательский json-объект. То, что я хочу сделать, это установить этот объект и внести все изменения, отраженные в приложении (входе/выходе из системы), без необходимости обновлять страницу.

Как бы это сделать с помощью AngularJS?

Ответ 1

Самый простой способ добиться этого - использовать службу. Например:

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

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

Затем вы можете ссылаться на это в любом из ваших контроллеров. Следующий код отслеживает изменения значения из службы (вызывая указанную функцию), а затем синхронизирует измененные значения с областью.

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

И тогда, конечно, вы можете использовать эту информацию, как вы считаете нужным; например в директивах, в шаблонах и т.д. Вы можете повторить это (настроенное на то, что вам нужно делать) в ваших контроллерах меню и т.д. Все это будет автоматически обновляться при изменении состояния службы.

Все, что более конкретно зависит от вашей реализации.

Надеюсь, это поможет!

Ответ 2

Я хотел бы изменить хороший ответ Джоша, добавив, что, поскольку AuthService, как правило, интересует кого-либо (скажем, любой, но имя входа в систему должно исчезнуть, если никто не зарегистрирован), может быть, более простой альтернативой будет уведомление заинтересованных сторон используя $rootScope.$broadcast('loginStatusChanged', isLoggedIn); (1) (2), в то время как заинтересованные стороны (например, контроллеры) будут слушать с помощью $scope.$on('loginStatusChanged', function (event, isLoggedIn) { $scope.isLoggedIn = isLoggedIn; }.

(1) $rootScope вводится как аргумент службы

(2) Обратите внимание, что в случае асинхронного входа в систему вам нужно уведомить Angular, что трансляция изменит ситуацию, включив ее в функцию $rootScope.$apply().

Теперь, говоря о сохранении контекста пользователя в каждом/многих контроллерах, вы не можете быть счастливы при прослушивании изменений входа в каждом из них и, возможно, предпочитаете слушать только в верхнем контроллере входа, а затем добавлять другие контроллеры, поддерживающие вход в систему как дети/встроенные контроллеры этого. Таким образом, детальный контроллер сможет видеть унаследованные свойства объекта $domain, такие как пользовательский контекст.