将承诺数据绑定到$ scope

时间:2014-04-23 05:02:04

标签: angularjs angularjs-scope

我设计了一个工厂,从网址获取数据并将其返回给控制器。 在控制器中,我打电话给这家工厂。 我用$ 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范围之外打印值时,都会出错。

2 个答案:

答案 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的工作方式感到困惑,您应该仔细阅读这个主题,但简而言之,您的代码就是这样运行的。

  1. barchart.drawChart()
  2. $ HTTP(); //工厂功能
  3. console.log(" Promise" + promise);
  4. console.log(" barchart data" + $ scope.barChartData.getSVG()); //那个()
  5. 之外的那个
  6. 我们在等待http req作为其异步时有一些潜在的等待时间我们永远不知道返回值所需的确切时间 - 这是承诺闪耀的地方!
  7. 则()
  8. $ scope.barChartData = data; //在承诺内
  9. console.log(" barchart data" + $ scope.barChartData.getSVG()); //在承诺内
  10. 你在评论中说,当你的承诺被退回时,你希望在外面解雇这个你可以用另一个承诺完成这个。

    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());
         });
    });