【发布时间】:2016-12-18 23:00:06
【问题描述】:
我是一个角度初学者,我正在尝试建立一个从我的 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(),这样您就可以在请求完成的准确时刻对异步请求的结果采取行动。
事后看来,这一切似乎都很明显,但希望这种解释在未来对其他人有所帮助......
感谢我收到的所有答案,他们对我帮助很大!
【问题讨论】:
-
console.log 是一个异步操作,并不总是在您期望的确切时间记录值。在您的控制器中,如果您将
console.log($scope.sessionStatus);更改为console.log(JSON.stringify($scope.sessionStatus));,那么它会输出什么?编辑:我怀疑您的 console.log 在返回承诺之前完成,这就是您无法访问该属性的原因。 -
@IthinkIcancode - 是的,看来你是对的。 JSON.stringify() 输出一个空对象。
-
@IthinkIcancode - 我能够通过使用 $timeout 在 console.log 调用上设置 2 秒延迟来记录所需的值,所以它似乎肯定是由异步引起的。
标签: javascript angularjs angularjs-factory angularjs-http