我正在使用Angular JS。我试图获得一个使用$ http服务获得的json对象,可以在$ scope变量中访问。在所有异步AJAX($ http.get())调用中,如果我尝试打印存储在$ scope变量中的数据并打印它,它会成功运行并向我显示预期的数据。但是在异步方法的外部范围内,分配了数据的同一$ scope变量将失去它并打印未定义。
代码:
var app = angular.module('chariot', ['ngRoute', 'ngFileUpload']);
app.factory('getTestcaseFactory', ['$http', '$routeParams', '$q', function($http, $routeParams, $q) {
return {
list: function(){
var deferred = $q.defer();
$http.get('/testcase/' + $routeParams.testcase)
.success(function(data, status, headers, config) {
deferred.resolve(data);
})
.error(function(data, status, headers, config) {
deferred.reject("Error fetching XML file: " + status + ' ' + JSON.stringify(headers));
});
return deferred.promise;
}
};
}
]);
app.controller('testcaseCapCtrl', ['$scope', '$routeParams', '$http', 'getTestcaseFactory', function($scope, $routeParams, $http, getTestcaseFactory) {
$scope.myjsonobj = '';
var fetchTestcaseDetails = function() {
getTestcaseFactory.list()
.then(
function(data) {
$scope.xml.file = data;
var x2js = new X2JS();
var jsonObj = x2js.xml_str2json($scope.xml.file);
$scope.xml.json = JSON.stringify(jsonObj, null, 2);
$scope.model = jsonObj;
console.log($scope.model);//PRINTS THE RIGHT DATA
},
function(data) {
alert(data);
});
}
fetchTestcaseDetails();
console.log($scope.model); //Prints undefined
}]);
答案 0 :(得分:0)
到时候
console.log($scope.model);
执行,$http
请求尚未通过,这就是它打印未定义的原因。完成$http
请求后,您的$scope.model
会相应更新。您可以使用$timeout
$timeout(function () {
console.log($scope.model);
}, 5000);
不要忘记在控制器中注入$timeout
。
答案 1 :(得分:0)
这节省了我的一天! $超时救援。谢谢@Dan摩尔多瓦的答案!由于$ http服务是异步的,我们必须设置一个定时器来等待一个时间间隔,直到在promise.success部分中真正接收数据,然后将它分配给$ scope内的变量。
var app = angular.module('chariot', ['ngRoute', 'ngFileUpload']);
app.factory('getTestcaseFactory', ['$http', '$routeParams', '$q', function($http, $routeParams, $q) {
return {
list: function(){
var deferred = $q.defer();
$http.get('/testcase/' + $routeParams.testcase)
.success(function(data, status, headers, config) {
deferred.resolve(data);
})
.error(function(data, status, headers, config) {
deferred.reject("Error fetching XML file: " + status + ' ' + JSON.stringify(headers));
});
return deferred.promise;
}
};
}
]);
app.controller('testcaseCapCtrl', ['$scope', '$routeParams', '$timeout', 'getTestcaseFactory', function($scope, $routeParams, $timeout, getTestcaseFactory) {
var fetchTestcaseDetails = function() {
getTestcaseFactory.list()
.then(
function(data) {
$scope.xml.file = data;
var x2js = new X2JS();
var jsonObj = x2js.xml_str2json($scope.xml.file);
$scope.xml.json = JSON.stringify(jsonObj, null, 2);
$scope.model = jsonObj;
console.log($scope.model);//PRINTS THE RIGHT DATA
},
function(data) {
alert(data);
});
}
fetchTestcaseDetails();
$timeout(function() {
console.log($scope.model); //Prints the Data now
}, 2000);
}]);
答案 2 :(得分:0)
到目前为止发布的解决方案是 fundemantally错误,因为它们依赖于任意超时,并且没有任何保证当时可以使用异步答案。
正如我在上面的评论中所建议的,这里还有两个数据/事件驱动的解决方案。
如果您希望在数据可用后运行名为processData
的函数,您已在示例中执行过解决方案1,请参阅以下行:
console.log($scope.model);//PRINTS THE RIGHT DATA
在这里你可以调用任何其他函数来触发进程的继续,只需调用任何函数:
console.log($scope.model);//PRINTS THE RIGHT DATA
processData();
使用angular的$ watch机制(2.):
$scope.$watch(
function(){return $scope.model;},
function(newValue, oldValue){
if(newValue != null){
console.log($scope.model);
processData();
}
})
这将在异步回调后打印数据,程序将继续处理。