Angularjs 将 ajax 数据缓存到服务中

Angularjs caches ajax data into a service

我有这么一个简单的场景,

应用程序从主视图(/main)开始,然后点击右上角按钮进入子视图(/sub)。

在应用程序启动期间 app.run(),用户的配置文件将被加载到服务 userService,一旦用户进入子视图,将从该服务读取该配置文件 userService 然后显示,这里是代码,

app.run(function($http, $rootScope, userService){
   $http.get('/profile').then(function(result){
        userService.setProfile(result.data.profile);
   });
});

app.service('userService', function(){
    var user = {}

    this.setProfile(profile){
        user.profile = profile;
    };

    this.getProfile(){
       return user.profile;
    }
});

在子视图中,调用了getProfile()来显示信息。

如果用户从Main View -> button -> Sub View开始,它会工作,但是,如果用户手动刷新Sub View或者只是从Sub View开始,getProfile()将没有任何显示,我知道那是因为在promise返回获取配置文件之前,已经进行了子视图。

我不喜欢直接动态地从子视图读取个人资料,因为我有其他页面也需要个人资料信息,那么有什么解决方法或更好的设计吗?谢谢。

我解决这个问题的方法是将相关数据添加到 $window.sessionStorage,大致如下(您需要使 $window 可用):

app.service('userService', function(){
  var user = {}
    if ($window.sessionStorage.profile)
        this.user.profile = JSON.parse($window.sessionStorage.profile)

  this.setProfile(profile){
      user.profile = profile;
      this.$window.sessionStorage.profile = JSON.stringify(profile)
  };

  this.getProfile(){
     return user.profile;
  }
});

而不是使用 app.run,您应该为此使用您的路线提供商。无论您使用 ngRoute 还是 ui-router,它们都具有解析功能。与其在 app.run 中获取您的个人资料,不如将其也移至 userService。

app.service('userService', function(){
    var self = this;
    self.user = {};

    self.getProfile = function() {
        return self.user.profile;
    };

    self.init = function() {
        return $http.get('/profile').then(function(result){
            self.user.profile = result.data.profile;
        });
    };
});

现在您的服务更像工厂了,您可以在路由提供程序中使用它的初始化。我使用 ui-router 但这也可以很容易地应用于 ngRoute。

我首先创建一个抽象状态来处理我可以处理的解决方案 'import' 在我需要的任何其他状态下。

.state('init', {
    abstract: true,
    resolve: ['userService', function(userService) {
        return userService.init();
    }]
});

现在我只是在其他状态下使用它,我可以确保userService已经初始化。

.state('subView', {
    parent: 'init',
    url: '/subView'
    //other state stuff like template, controller, etc
});