Как обрабатывать обновление страницы с помощью приложения AngularJS с одной страницей
две проблемы беспокоили меня, как я узнал угловой:
как восстановить состояние, когда пользователь обновляет страницу или нажимает кнопку Назад?
как обмениваться данными между областями, принадлежащими к разным контроллерам?
ниже я показываю простое решение, которое использует хранилище сеансов на стороне клиента. Он позволяет как для совместного использования общих данных, так и для автоматического восстановление состояния после обновления страницы или нажатия кнопки "Назад".
Примечание: решение ниже оказалось необходимым для ответа на следующий вопрос:
как заставить кнопку "Назад" работать с государственной машиной AngularJS ui-router?
3 ответов
решение зависит от SessionService
класс, показанный ниже. Синтаксис-coffeescript.
SessionService Класс
class SessionService
scopes:[]
setStorage:(key, value) ->
scope[key] = value for scope in @scopes
value = if value is undefined then null else JSON.stringify value
sessionStorage.setItem key, value
getStorage:(key)->
sessionValue = sessionStorage.getItem key
if sessionValue == "undefined"
return null
JSON.parse sessionValue
register:(scope)->
for key, value of sessionStorage
scope[key] = if value? and value != "undefined" then JSON.parse(value) else null
@scopes.push scope
scope.$on '$destroy', =>
@scopes = @scopes.filter (s) -> s.$id != scope.$id
clear: ->
@setStorage(key, null) for key of sessionStorage
isAuthenticated: ->
@accessor 'isAuthenticated', value
user:(value=null) ->
@accessor 'user', value
# other storage items go here
accessor:(name, value)->
return @getStorage name unless value?
@setStorage name, value
angular
.module 'app.Services'
.service 'sessionService', SessionService
на SessionService
класс определяет isAuthenticated
свойство (простой bool) и user
свойство (сложный объект). Значения этих свойств автоматически строятся / анализируются по мере их хранения / извлечения с помощью локального sessionStorage
объект, поставляемый javascript.
добавить
я столкнулся с той же проблемой и решил использовать угловые куки, так как только состояние, которое не вытягивается шаблоном через ng-init, является зарегистрированным пользователем государство.
Я храню идентификатор пользователя в файле cookie при входе в систему после получения пользователя
модель с нашего сервера, и я очищаю файл cookie ID пользователя при выходе из системы. Затем, чтобы восстановить
состояние пользователя, вошедшего в систему, на событии обновления страницы или кнопки "назад", я подключаю
$location
услуги $locationChangeStart
событие. Из моих экспериментов, это
событие срабатывает в точке, местоположение вот-вот изменится, но до
частичный / шаблон загружен. Это позволяет загружать необходимое состояние только
во время.
Я не уверен, что у меня нет гонки здесь
$scope.loadLoggedInUser(...)
использует asynch $http для загрузки необходимого состояния, но до сих пор
это сработало надежно для меня.
$scope.$on('$locationChangeStart', function() {
$log.debug("locationChangeStart");
if (!$scope.appCtx.models.loggedInUser) {
var userID = $cookies.get("userID");
if (!userID) {
$scope.doLogout();
return;
}
$scope.loadLoggedInUser(userID, true);
}
});
есть простое решение, когда вы используете узел.js для настройки сервера. Вы должны организовать маршрутизацию на стороне клиента таким образом, чтобы ссылки маршрута были уникальными регулярными выражениями. В приложении.js у вас будет:
(function () {
var app = angular.module('dataCollector', ['ngRoute']);
app.config(['$routeProvider', '$locationProvider',
function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'home.html',
controller: 'mainController'
})
.when('/about', {
templateUrl: 'about.html',
controller: 'aboutController'
})
.when('/login', {
templateUrl: 'login.html',
controller: 'loginController'
});
$locationProvider.html5Mode(true);
}]);
app.controller('mainController', ['$scope', function ($scope) {
}]);
})();
в этом примере все маршруты, кроме '/'
, может быть записано в схеме регулярного выражения [A-Za-z]
. Имея это, сервер.файл JS будет выглядеть так:
var express = require('express');
var http = require('http');
var fs = require('fs');
var path = require('path');
var app = express();
app.use(express.static('public'));
app.get(/[A-Za-z]/, function (req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
http.createServer(app).listen(80);
теперь каждый GET
запрос соответствует регулярному выражению [A-Za-z]
будет ответ с index.html
(это наши маршруты, вызываемые при обновлении страницы, например /about
). Любой другой GET
запрос будет ответ с файлом из /public
directory (здесь каждый файл с расширением *.html
). Это позволяет правильно обновить спа-салон AngularJS.