我有这个角度控制器:
app.controller('FeedCtrl', function ($scope, Profile) {
$scope.getID = function() {
Profile.getUID()
.then(function (data) {
if (data !== null) {
console.log(data.id); // returns correct id
$scope.data = data;
} else {
console.log("Could not retrieve id");
}
}, function (error) {
console.log(error);
});
console.log($scope.data); // logs: undefined
return $scope.data; // logs: undefined
};
var somedata = $scope.getID();
console.log(somedata); //just returns undefined
});
控制器用于JSON请求的此工厂。
module.factory('Profile', function($http, $localStorage) {
return {
getUID:function(){
return $http.get("https://graph.facebook.com/v2.2/me", {params: { access_token: $localStorage.accessToken, fields: "id,name,gender,location,website,picture,relationship_status", format: "json" }})
.then(function(response) {
if (typeof response.data === 'object') {
return response.data;
} else {
// invalid response
return $q.reject(response.data);
}
}, function(response) {
// something went wrong
return $q.reject(response.data);
});
}
};
});
我无法更改$ scope.data的值,以便在$ scope.getID函数之外使用,但在FeedCtrl的其余部分内部。
如果您查看评论,您会看到我在控制台日志中返回的内容。
我试图通过在StackOverflow和Google中搜索来了解这个问题,但似乎我不理解AngularJS的$ scope概念。
我很感激任何正确的方向。
答案 0 :(得分:3)
这是一个经典错误,您调用的代码是异步的,查看您的控制台并查看日志的顺序,将返回正确ID的日志将是最后一个,因为它将仅在调用之后调用承诺已经解决。
这对你来说是否足以推动正确的方向?
非常简单example,但原则相同。
setTimeout(function(){
document.write('A2: Timeout is done');
}, 5000);
document.write('A1: Called timeout, this gets logged before A2 even though my line number is higher.');
答案 1 :(得分:3)
这不是范围问题,而是时间问题。您试图在值存在之前使用该值。
在控制器中,您只能在结果到达后使用该值,即在then
方法的回调中。 <{1}}语句在结果出现之前运行,因此您无法返回。
进行异步调用后,必须异步处理结果。您可以返回一个return
对象来处理结果,但是您永远不能创建一个异步调用函数并返回结果本身。
答案 2 :(得分:2)
您的代码是异步的。我在这篇文章中对这个完全相同的问题写了回应。