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
});
我有这么一个简单的场景,
应用程序从主视图(/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
});