我正在创建一个工厂来从一个页面获取 userId,调用 REST API,然后在以下 View 中返回结果。我最初的尝试主要取自this answer但是 - 不出所料 - 我一直陷入这样的情况: 没有及时响应并且 get()
方法返回一个空数组。
这是工厂本身
app.factory('GetMessages', function() {
var messages = []
function set(userId) {
Restangular.all('/api/messages/').getList({'_id': userId}).then(function(docs){
messages = docs
})
}
function get() {
return messages;
}
return {
set: set,
get: get
}
});
就其值(value)而言,我可以毫无困难地将 userId 放入工厂,因为它只是传递给这样的函数
查看:
<a ng-click='passToFactory(message.user.id)' href='/home/inbox/reply'>Reply</a>
Controller :
$scope.passToFactory = function(id) {
GetMessages.set(id);
};
以下 View 的 Controller 只是
$scope.messages = GetMessages.get()
我遇到的问题是,工厂返回空集后,无法识别工厂的进一步更改(即使经过一段时间后,它确实从 API 获得了正确的响应)和 $scope.messages
仍然是空的。
我尝试将 API 调用移至 get 方法(这没有起作用,因为 get 方法通常无法及时获取 userId
),并且我找不到使用 Promise 的方法力get()
等待set()
完成。
我更愿意在最终的解决方案中继续使用 Restangular,但这是一件小事,花费了太多时间,因此任何修复都有效。
我对 Angular 还很陌生,所以我确信有一些东西是完全显而易见的,但现在我只是迷路了。谢谢。
最佳答案
您遇到的竞争条件是 .then
方法内的函数在调用 set 函数之后异步执行。如果 get 函数在 $q
服务履行 promise 之前执行,则 get 函数将返回一个空数组。
解决方案是保存 promise 中的 promise 和链。
app.factory('GetMessages', function() {
var promise;
function set(userId) {
promise = Restangular.all('/api/messages/').getList({'_id': userId});
}
function get() {
return promise;
}
return {
set: set,
get: get
}
});
在你的 Controller 中,链接来自 promise 。
GetMessages.get.then( function (docs) {
$scope.messages = docs;
}) .catch ( function (error) {
//log error
};
有关链接 promise 的更多信息,请参阅 AngularJS $q Service API Reference -- chaining promises .
关于javascript - 如何创建具有 getter 和 setter 方法的 Angular 工厂而不遇到竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34737870/