AngularJS变量的变量范围/嵌套

时间:2015-03-29 19:18:46

标签: javascript angularjs angularjs-scope

我有这个角度控制器:

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概念。

我很感激任何正确的方向。

3 个答案:

答案 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)

您的代码是异步的。我在这篇文章中对这个完全相同的问题写了回应。

Returning after ajax call prints false