能够访问服务返回的对象,但访问其属性会给出未定义的
Able to access object returned by service, but accessing its properties gives undefined
我是一个 angular 初学者,我正在尝试建立一个从我的 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);
我只是在控制台中得到 undefined。
我做错了什么?
编辑
对于任何其他患有我独特的迟钝品牌的人,这是我得出的结论:
问题的主要原因是我一直在尝试访问 $http 服务返回的异步生成的信息,该信息在它的 promise 被解决之前(即在 .then()
完成执行之前),这是导致记录未定义,因为数据实际上尚未定义,因为在控制器中调用 console.log()
时生成数据的请求仍在进行中。
使用 $timeout 服务我能够延迟 console.log()
的调用,这导致数据被正确记录到控制台。
$timeout(function(){
console.log($scope.sessionStatus.session);
}, 2000); // logs "false" to the console like originally expected
我之前的想法是,我应该在控制器中尽可能短地调用我的工厂方法,然后在调用之外根据其结果采取行动。这显然是个坏主意,因为 .then()
存在,因此您可以在请求完成的准确时刻对异步请求的结果采取行动。
事后看来,这一切似乎都很明显,但希望这个解释能在未来帮助其他人...
感谢我收到的所有答复,他们帮了我大忙!
因为 javascript 是异步的,它不会等到 http 响应和 return 状态。这就是为什么它 return 为空。尝试这样的事情
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);
});
}]);
尝试return你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');
}
}]);
然后在控制器:
app.controller('headerCtrl', ['$scope', 'sessionStatus', function($scope, sessionStatus) {
function getSuccess(response) {
$scope.sessionStstus = response.data;
}
function getError(response) {
console.log('error');
}
sessionStatus.status()
.then(getSuccess)
.catch(getError);
console.log($scope.sessionStatus);
}]);
您可以对此处的代码进行一些更改。首先,我建议解决承诺并在控制器中而不是在服务中分配值。接下来,您不需要在结果对象上使用 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
});
}]);
我是一个 angular 初学者,我正在尝试建立一个从我的 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);
我只是在控制台中得到 undefined。
我做错了什么?
编辑
对于任何其他患有我独特的迟钝品牌的人,这是我得出的结论:
问题的主要原因是我一直在尝试访问 $http 服务返回的异步生成的信息,该信息在它的 promise 被解决之前(即在 .then()
完成执行之前),这是导致记录未定义,因为数据实际上尚未定义,因为在控制器中调用 console.log()
时生成数据的请求仍在进行中。
使用 $timeout 服务我能够延迟 console.log()
的调用,这导致数据被正确记录到控制台。
$timeout(function(){
console.log($scope.sessionStatus.session);
}, 2000); // logs "false" to the console like originally expected
我之前的想法是,我应该在控制器中尽可能短地调用我的工厂方法,然后在调用之外根据其结果采取行动。这显然是个坏主意,因为 .then()
存在,因此您可以在请求完成的准确时刻对异步请求的结果采取行动。
事后看来,这一切似乎都很明显,但希望这个解释能在未来帮助其他人...
感谢我收到的所有答复,他们帮了我大忙!
因为 javascript 是异步的,它不会等到 http 响应和 return 状态。这就是为什么它 return 为空。尝试这样的事情
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);
});
}]);
尝试return你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');
}
}]);
然后在控制器:
app.controller('headerCtrl', ['$scope', 'sessionStatus', function($scope, sessionStatus) {
function getSuccess(response) {
$scope.sessionStstus = response.data;
}
function getError(response) {
console.log('error');
}
sessionStatus.status()
.then(getSuccess)
.catch(getError);
console.log($scope.sessionStatus);
}]);
您可以对此处的代码进行一些更改。首先,我建议解决承诺并在控制器中而不是在服务中分配值。接下来,您不需要在结果对象上使用 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
});
}]);