【问题标题】:Angularjs caches ajax data into a serviceAngularjs 将 ajax 数据缓存到服务中
【发布时间】:2015-12-03 04:40:34
【问题描述】:

我有这么简单的场景,

应用程序从主视图(/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() 来显示信息。

如果用户从主视图 -> 按钮 -> 子视图开始,它可以工作,但是,如果用户手动刷新子视图或只是从子视图开始,getProfile() 将没有任何显示,我知道这是因为在@之前987654330@ 获取配置文件返回,子视图已进行。

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

【问题讨论】:

  • 您可以在加载子视图之前解析配置文件:stackoverflow.com/questions/19937751/…
  • run 不会等待请求完成...如前所述在路由器中使用resolve。如果使用 ui-router 和父状态,问题真的很简单
  • @BroiSates @charlietfl 我觉得resolve 不太方便,我必须配置每个路由器以将配置文件注入其控制器
  • 这就是为什么使用 ui-router 和父状态如此有用,您在父级别只有一个解决方案
  • @charlietfl 会预加载初始化数据,然后手动进行角度引导,在应用程序运行中设置这个userService 是一个好习惯吗?

标签: ajax angularjs angularjs-service


【解决方案1】:

我解决这个问题的方法是将相关数据添加到 $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;
  }
});

【讨论】:

  • 这可以解决,但是,profile 将成为一个“公共”变量,您甚至可以从userService 之外进行修改,还不够好。
【解决方案2】:

您可能应该使用您的路由提供程序,而不是使用 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。

我首先创建一个抽象状态来处理我可以解决的问题,而不是在我需要的任何其他状态中“导入”。

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

【讨论】:

  • 是的,事实上我改变了基于 cmets 的类似方式,现在我正在考虑预加载初始化数据然后手动角度引导,在应用程序运行中我将设置这个 userService,您对此有何看法,哪个是更好的做法?
  • 我认为这只是完成同一件事的两种方式。我不是角度大师,所以我真的不能说哪个更好,因为对我来说两者似乎都是引导数据的好方法。将它加载到 app.run 中是一个并且在使用路由器方法时完成,需要您将它包含在每个路由中,这样确实可以节省一些代码,但是我喜欢能够选择我想要的路由。
猜你喜欢
  • 1970-01-01
  • 2016-09-23
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 2014-07-26
相关资源
最近更新 更多