能够访问服务返回的对象,但访问其属性会给出未定义的

时间:2016-08-12 03:18:33

标签: javascript angularjs angularjs-factory angularjs-http

我是一个有角度的初学者,我正在尝试建立一个从我的php后端获取数据并更新控制器的工厂。这是我的基本代码:

工厂

app.factory('sessionStatus', ['$http', function($http){
    return {
        status:function(){
            var status = {};
            $http.get('/game_on/api/api.php?session-status')
            .then(function(response){
                angular.copy(response.data, status);
            });
            return status;
        }
    };
}]);

控制器

app.controller('headerCtrl', ['$scope', 'sessionStatus', function($scope, sessionStatus){

    $scope.sessionStatus = sessionStatus.status();

    console.log($scope.sessionStatus);

}]);

这在控制台中给出了以下内容:

Object{}
  session:"false"

但是,当我调整控制器以记录会话属性的值时,如下所示:

console.log($scope.sessionStatus.session);

我只是在控制台中未定义。

我做错了什么?

修改

对于那些遭受我独特品牌迟缓的人来说,这是我得出的结论:

问题的主要原因是我一直在尝试访问$ http服务返回的异步生成的信息,然后才解决其承诺(即.then()执行完毕之前),这导致未定义被记录,因为数据实际上尚未定义,因为在控制器中调用console.log()时,生成它的请求仍在进行中。

使用$ timeout服务我能够延迟调用console.log(),这导致数据被正确记录到控制台。

$timeout(function(){
    console.log($scope.sessionStatus.session);
}, 2000); // logs "false" to the console like originally expected

我之前的想法是,我应该在控制器内尽可能地调用我的工厂方法,然后在该调用之外对其结果进行操作。这显然是一个坏主意,因为.then()存在,因此您可以在请求完成的确切时刻对异步请求的结果进行操作。

事后看来,这一切看起来都很明显,但希望这个解释能帮助其他人......

感谢我收到的所有答案,他们是一个很大的帮助!

3 个答案:

答案 0 :(得分:1)

您可以在此处对代码进行一些更改。首先,我建议解决承诺并在控制器中而不是在服务中分配值。接下来,您不需要在结果对象上使用Angular.Copy,您只需进行变量赋值即可。尝试像这样的东西,然后构建:

app.factory('sessionStatus', ['$http', function($http){

    return {status: $http.get('/game_on/api/api.php?session-status')}

}]);

app.controller('headerCtrl', ['$scope', 'sessionStatus', function($scope, sessionStatus){

    sessionStatus.status.then(function(result){
        $scope.sessionStatus = result.data; //or some property on result
    });

}]);

答案 1 :(得分:0)

因为javascript是异步的,它不会等到http响应并返回状态。这就是为什么它返回null。试试这样的事情

   app.factory('sessionStatus', ['$http', function($http){
            return {
                status:function(){
                 $http.get('/game_on/api/api.php?session-status')
                }
            };
        }]);

        app.controller('headerCtrl', ['$scope', 'sessionStatus', function($scope, sessionStatus){

            $scope.sessionStatus = sessionStatus.status().then(function(response) { 
               console.log(response);
        });


    }]);

答案 2 :(得分:0)

尝试从.animate-show.ng-hide-add, .animate-show.ng-hide-remove { transition: all linear 0.5s; display: block !important; } .animate-show.ng-hide-add.ng-hide-add-active, .animate-show.ng-hide-remove { opacity: 0; } .animate-show.ng-hide-add, .animate-show.ng-hide-remove.ng-hide-remove-active { opacity: 1; }

返回承诺
factory

然后在控制器

app.factory('sessionStatus', ['$http', function($http) {
  var factory = {
    status: status
  };

  return factory;

  function status() {
    return $http.get('/game_on/api/api.php?session-status');
  }
}]);