我设计了一个工厂,从网址获取数据并将其返回给控制器。 在控制器中,我打电话给这家工厂。 我用$ q来解决承诺。 从控制器调用工厂时,我试图将返回的值分配给范围。 在我尝试访问范围中的值时分配值后,我得到消息undefined 你能帮我解决这个问题吗
app.factory('barchart', function($http,$q) {
var factory={};
factory.drawChart=function() {
var deferred=$q.defer();
$http({
method: 'GET',
url: 'ActionServlet',
headers: {'Content-Type': 'application/json' },
params: {country: "densityplot"}
})
.success(function (data, status, headers, config) {
deferred.resolve(data);
})
.error(function (data, status, headers, config) {
// something went wrong :(
});
return deferred.promise;
};
return factory;
});
app.controller('mycontroller',function($scope, $http, barchart) {
var promise = barchart.drawChart();
console.log("Promise " + promise);
promise.then(function(data) {
$scope.barChartData = data;
console.log("barchart data " + $scope.barChartData.getSVG());
});
console.log("barchart data " + $scope.barChartData.getSVG());
});
但是当它在范围内时它会显示数据。 每当我尝试在promises范围之外打印值时,都会出错。
答案 0 :(得分:2)
Angular's $http执行异步操作。您的then
如下
promise.then(function(data) {
$scope.barChartData = data;
console.log("barchart data " + $scope.barChartData.getSVG());
});
接收数据$http
是通过其异步操作完成的。它将数据放入变量并打印出来,一切正常。
但是,当您尝试在该范围之外登录时
promise.then(function(data) {
$scope.barChartData = data;
console.log("barchart data " + $scope.barChartData.getSVG());
});
console.log("barchart data " + $scope.barChartData.getSVG());
$http
尚未完成其操作,因此$scope.barChartData
仍未定义。
您的then
只是告诉控制器在收到工厂承诺时该怎么做。仅仅因为那段代码高于单独的日志并不意味着它按照该顺序被调用。
答案 1 :(得分:0)
问题是在promise被返回之前触发了promise之外的控制台语句...因此未定义......
app.controller('myController', function($scope, barchart) {
barchart.drawChart()
.then(function(data) {
$scope.barChartData = data;
console.log("barchart data " + $scope.barChartData.getSVG());
});
console.log("barchart data " + $scope.barChartData.getSVG());
});
一方不太好......你的$ http服务实际上是返回一个函数对象吗?这看起来很奇怪,但并非不可能:
$scope.barChartData.getSVG();
如果您对asynchronousity JS的工作方式感到困惑,您应该仔细阅读这个主题,但简而言之,您的代码就是这样运行的。
你在评论中说,当你的承诺被退回时,你希望在外面解雇这个你可以用另一个承诺完成这个。
app.controller('myController', function($scope, $q, barchart) {
var requestFinished = $q.defer();
barchart.drawChart()
.then(function(data) {
$scope.barChartData = data;
console.log("barchart data " + $scope.barChartData.getSVG());
requestFinished.resolve();
});
requestFinished.promise.then(function() {
console.log("barchart data " + $scope.barChartData.getSVG());
});
});