Как обрабатывать обновление страницы с помощью приложения AngularJS с одной страницей

две проблемы беспокоили меня, как я узнал угловой:

  1. как восстановить состояние, когда пользователь обновляет страницу или нажимает кнопку Назад?

  2. как обмениваться данными между областями, принадлежащими к разным контроллерам?

ниже я показываю простое решение, которое использует хранилище сеансов на стороне клиента. Он позволяет как для совместного использования общих данных, так и для автоматического восстановление состояния после обновления страницы или нажатия кнопки "Назад".

Примечание: решение ниже оказалось необходимым для ответа на следующий вопрос:

как заставить кнопку "Назад" работать с государственной машиной 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.