我在Chrome扩展程序中运行了一个简单的AngularJS应用程序,该应用程序使用了Storage API。存在异常的存储问题;我已经将存储抽象为“UserService”,它将数据设置并作为工厂获取:
app.factory('UserService',
function($q, AppSettings) {
var defaults = {
api: {
token: AppSettings.environments[1].api.token
},
email: ''
};
var service = {
user: {},
save: function() {
chrome.storage.sync.set({'user': angular.toJson(service.user)});
},
restore: function() {
var deferred = $q.defer();
chrome.storage.sync.get('user', function(data) {
if(!data) {
chrome.storage.sync.set({'user': defaults});
service.user = defaults;
} else {
service.user = angular.fromJson(data.user);
}
deferred.resolve(service);
});
return deferred.promise;
}
};
// set the defaults
service.restore().then(function(data) {
console.log(data);
return data;
});
});
上面的console.log()
调用会按预期转储数据。但是,当我在其他工厂中包含UserService时(我有一个使用特定于用户的API令牌的APIService),UserService参数在下面的代码中被标记为“未定义”:
app.factory('APIService',
function($resource, $http, UserService, AppSettings) {
var token = UserService.user.api.token;
...
});
我确信在整个应用程序中消费已解决的承诺方面,我并没有完全掌握Angular承诺模式。
更新代码:
app.factory('UserService',
function($q, AppSettings) {
var defaults = {
api: {
token: AppSettings.environments[1].api.token
},
email: ''
};
var service = {
user: {},
save: function() {
chrome.storage.sync.set({'user': angular.toJson(service.user)});
},
restore: function() {
var deferred = $q.defer();
chrome.storage.sync.get('user', function(data) {
if(!data) {
chrome.storage.sync.set({'user': defaults});
service.user = defaults;
} else {
service.user = angular.fromJson(data.user);
}
deferred.resolve(service.user);
});
return deferred.promise;
}
};
// set the defaults
service.restore().then(function(data) {
console.log(data);
return data;
});
return service;
});
编辑/其他信息:
好的,靠近。已经重构,以便我正确地返回对象,但现在的问题是,当APIService
被创建并尝试使用UserService
对象的属性时,它们根本就不存在,因为它们仅在解析异步还原方法后创建。因此,不可能访问UserService.user.api.token
属性,因为此时它不存在,所以问题是,如果在那时我不需要它,如何在需要时获取APIService中的数据?我试图避免将APIService
的全部内容放入一个回调中,该回调在一个假定的新UserService.get()
方法之后触发,该方法在解析promise时调用回调。任何最终指导都表示赞赏。
答案 0 :(得分:2)
您没有从工厂退回物品。因此,当您尝试注入UserService
参数时,它会提供undefined,因为您还没有从UserService函数返回任何内容。
如果您退回service
变量,我认为您将获得您正在寻找的行为。
答案 1 :(得分:2)
您的服务有误。请看我的修复:
app.factory('UserService',
function($q, AppSettings) {
var defaults = {
api: {
token: AppSettings.environments[1].api.token
},
email: ''
};
var service = {
user: {},
save: function() {
chrome.storage.sync.set({'user': angular.toJson(service.user)});
},
restore: function() {
var deferred = $q.defer();
chrome.storage.sync.get('user', function(data) {
if(!data) {
chrome.storage.sync.set({'user': defaults});
service.user = defaults;
} else {
service.user = angular.fromJson(data.user);
}
deferred.resolve(service.user); // <--- return the user in here
});
return deferred.promise;
}
};
// set the defaults
service.restore().then(function(data) {
console.log(data);
return data;
});
return service; // <--- return the service to be used injected when injected
});
[编辑] 回答你的新问题:不要直接访问用户。在您的服务中创建一个新函数,如返回promise的getUser()。在该函数中,如果用户已经被检索,则返回该用户,否则返回restore()函数:
var service = {
user: null,
getUser: function() {
if (service.user)
{
var deferred = $q.defer();
deferred.resolve(service.user);
return deferred.promise;
}
else
return service.restore();
},
save: function() {
chrome.storage.sync.set({'user': angular.toJson(service.user)});
},
restore: function() {
var deferred = $q.defer();
chrome.storage.sync.get('user', function(data) {
if(!data) {
chrome.storage.sync.set({'user': defaults});
service.user = defaults;
} else {
service.user = angular.fromJson(data.user);
}
deferred.resolve(service.user); // <--- return the user in here
});
return deferred.promise;
}
};