我有一个工厂发送 POST 请求来获取一些 JSON 键值对:
.factory('Rest', ['$resource',
function($resource) {
// returns JSON key-value pairs, e.g. "{'foo', 'bar'}"
return $resource('rest/get', {}, {
get: {
method: 'POST'
}
});
}])
我有另一个工厂打算暴露给 Controller ,以便在给定键的情况下访问键值对:
.factory('Pairs', ['Rest',
function(Rest) {
var pairs;
Rest.get(function(response) {
pairs = response;
});
return {
get: function(key) {
return pairs[key];
}
};
}])
问题是,当我调用 Pairs.get('foo')
时,Pairs
工厂的 pairs
对象不是尚未初始化(因为 Rest.get
是异步的),因此导致 TypeError: Cannot read property 'foo' of undefined
:
.controller('AnyController', ['Pairs',
function (Pairs) {
console.log(Pairs.get('foo')); // error
}])
知道如何解决这个问题吗?
最佳答案
正如您在问题中所述,Rest.get
是异步的,因此您的 Pairs.get
也必须是异步的。您可以按以下方式实现它:
.factory('Pairs', ['Rest', '$q',
function(Rest, $q) {
var pairs;
var deferredList = [];
Rest.get(function(response) {
pairs = response;
angular.forEach(deferredList, function(o) {
o.deferred.resolve(pairs[o.key]); // resolve saved defer object
});
deferredList = null; // we don't need the list anymore
});
return {
get: function(key) {
if (pairs) {
return $q.when(pairs[key]); // make immediate value as a promise
}
var deferred = $q.defer(); // create a deferred object which will be resolved later
deferredList.push({ // save both key and deferred object for later
key: key,
deferred: deferred
});
return deferred.promise;
}
};
}])
然后像这样使用它:
Pairs.get('foo').then(function(value) {
console.log(value);
});
关于javascript - 访问通过启动异步请求的工厂初始化的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21267559/