本文介绍了如何使用 AngularJS 单页应用程序处理页面刷新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我学习 angular 的过程中,有两个问题困扰着我:

Two problems have troubled me as I have learned angular:

  1. 如何在用户刷新页面或点击后退按钮时恢复状态?

如何在属于不同控制器的范围之间共享数据?

下面我展示了一个使用客户端会话存储的简单解决方案.它允许共享公共数据并在用户刷新页面或点击后退按钮后自动恢复状态.

Below I show a simple solution that makes use of client-side session storage. It allows for both the sharing of common data and the automatic restoration of state after a user refreshes the page or hits the back button.

注意:事实证明,以下解决方案对于回答以下问题至关重要:

Note: The solution below proved essential to answer the following question:

如何让后退按钮与 AngularJS ui-router 状态机配合使用?

推荐答案

解决方案依赖于如下所示的 SessionService 类.语法是咖啡脚本.

The solution depends on the SessionService class shown below. The syntax is 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 属性(一个复杂的对象).这些属性的值在使用 javascript 提供的客户端本地 sessionStorage 对象存储/检索时会自动字符串化/解析.

The SessionService class defines the isAuthenticated property (simple bool) and the user property (a complex object) . The values of these properties are automatically stringified / parsed as they are stored / retrieved using the client-side local sessionStorage object supplied by javascript.

您可以根据需要添加更多属性.像 $rootScope 一样,您可以谨慎地添加属性.与 $rootScope 不同,属性值在页面刷新或单击后退按钮后仍然可用.

You add more properties as required. Like $rootScope you add properties sparingly. Unlike $rootScope the property values are still available after a page refresh or back button click.

该服务允许向其注册任意数量的范围.注册作用域后,sessionStorage 中的所有存储值都会自动分配给该作用域.通过这种方式,所有已注册的作用域始终可以访问所有会话属性.

The service allows any number of scopes to be registered with it. When a scope is registered all the stored values in sessionStorage are automatically assigned to that scope. In this way all the registered scopes always have access to all the session properties.

更新属性值时,所有注册的范围都会更新其对应的值.

When a property value is updated, all the registered scopes have their corresponding values updated.

当 angular 销毁作用域时,它会自动从注册作用域列表中删除,以节省资源.

When angular destroys a scope it is automatically removed from the list of registered scopes to save wasting resources.

如果用户刷新页面或点击后退按钮,Angular 应用程序将被迫重新启动.通常这意味着您必须重建您当前的状态.SessionService 会自动为您执行此操作,因为在应用程序初始化期间注册时,每个范围都会从本地存储恢复其值.

If a user refreshes the page or hits the back button then the angular application is forced to restart. Normally this would mean you would have to reconstruct your current state. The SessionService does this for you automatically as each scope will have its values restored from local storage when they are registered during the app initialisation.

所以现在很容易解决在范围之间共享数据以及在用户刷新或点击后退按钮时恢复值的问题.

So now it is easy to solve the problem of both sharing data between scopes as well as restoring values when the user refreshes or hits the back button.

以下是一些示例 Angular 代码,展示了如何使用 SessionService 类.

Here is some sample angular code that shows how to use the SessionService class.

在某个控制器中向 SessionService 注册一个作用域

angular
.module 'app'
.controller 'mainCtrl', ($scope, $state, session, security) ->
    #register the scope with the session service
    session.register $scope

    #hook up the 'login' method (see security service)
    $scope.login = security.login

    # check the value of a session property
    # it may well be true if the page has been refreshed
    if session.isAuthenticated
        $state.go('home')
    else
        $state.go('login')

在服务中设置会话值

 class SecurityService
    @$inject:['$http','sessionService', 'api']
    constructor:(@http, @session, @api) ->

    login:(username, password) =>
        @http.get "#{@api.base}/security/login/credentials/#{username}/#{password}"
        .success (user)=>
            @session.isAuthenticated = true
            @session.user = user
        .error (ex)=>
            # process error

angular
.module 'app'
.service 'securityService', SecurityService

在 UI 中使用会话值(Jade 模板)

div(ng-show="isAuthenticated")
    div Hello {{user.Name}}

这篇关于如何使用 AngularJS 单页应用程序处理页面刷新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 13:42