Як зберегти поточний контекст користувача в AngularJS?


92

У мене є AuthService, яка реєструє користувача, він повертає користувацький json-об'єкт. Що я хочу зробити, це встановити цей об’єкт, і всі зміни відображатимуться у програмі (вхід / вихід із системи) без необхідності оновлювати сторінку.

Як би я досяг цього за допомогою AngularJS?

Відповіді:


180

Найпростіший спосіб досягти цього - скористатися послугою. Наприклад:

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();
  });
});

І тоді, звичайно, ви можете використовувати цю інформацію, як би не вважали за потрібне; наприклад, у директивах, у шаблонах тощо. Ви можете повторити це (з урахуванням того, що вам потрібно зробити) у своїх контролерах меню тощо. Все це буде оновлено автоматично, коли ви зміните стан служби.

Щось більш конкретне залежить від вашої реалізації.

Сподіваюся, це допомагає!


28
@ChrisNicola Насправді, в AngularJS всі служби є однопрофільними. Отже, служба створюється в перший раз, коли вона запитується (тобто контролером або іншою службою), і всі наступні запити на неї повертають точно такий самий екземпляр.
Джош Девід Міллер

2
Це може бути, але як функцію ми можемо видалити внутрішні елементи того, як ми зберігаємо цю інформацію, із загальнодоступного API у приватний API. Це робить рефакторинг пізніше набагато простішим. Але функція все одно поверне логічне значення.
Джош Девід Міллер,

7
Це може бути дурним запитанням ... але що станеться, якщо користувач оновить сторінку - чи не загублена інформація для входу?
Томба

10
@Tomba Це гарне запитання. :-) Дійсно, інформація втрачається під час оновлення. Зазвичай вам потрібно буде зберегти певну інформацію про сеанс у файлі cookie. Цю інформацію про сеанс можна також перевірити під час налаштування AuthService. Це допомагає не лише для оновлення сторінки, але й для тих, хто відкриває посилання в новій вкладці.
Джош Девід Міллер

2
@PixMach Ви на 100% праві щодо кривої навчання. Ваше запитання буде залежати багато від конкретного випадку, але ось кілька загальних закономірностей. Слідкуйте за розділенням проблем: користувальницький інтерфейс, пов’язаний із ініціалізацією входу, є окремим від самого аутентифікації, який відокремлений від стану автентифікації, який відокремлений від будь-якого меню, яке може залежати від зазначеного стану. Навігація / меню часто найкраще обробляється одним контролером, а вкладені стани (а-ля ui-router) та вирішення маршрутів - хороший спосіб зберегти сухим контроль автентифікації. Те, що ви написали, звучить правильно.
Джош Девід Міллер,

5

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

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

(2) Зверніть увагу, що у вірогідному випадку асинхронної операції входу в систему ви хочете повідомити Angular про те, що трансляція змінить ситуацію, включивши її у $rootScope.$apply()функцію.

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


4
Призначений за неправильне пояснення заводської функції. Це непорозуміння вже було вирішено в цьому коментарі за кілька місяців до того, як ви опублікували свою відповідь.
Rhys van der Waerden
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.