AngularJS图表指令 - 异步服务中加载的数据不更新图表

时间:2014-01-06 16:56:24

标签: angularjs angularjs-directive angularjs-scope

我正在创建一个图表指令,并且在加载google api后我正在引导应用程序。在下面的代码中,一个简单的数据表工作正常。但是当我以异步方式从服务器加载数据时,图表没有显示。

控制器

'use strict';

myNetaInfoApp.controller('allCandidatesController', [
    '$scope','allCandidates2009Svc', '$timeout',
    function ($scope, allCandidates2009Svc, $timeout) {
        $scope.data1 = {};
        $scope.data1.dataTable = new google.visualization.DataTable();
        $scope.data1.dataTable.addColumn("string", "Party");
        $scope.data1.dataTable.addColumn("number", "qty");
        $scope.data1.dataTable.title = "ASDF";
        $timeout( function (oldval, newval) {
            allCandidates2009Svc.GetPartyCriminalCount().then(function(netasParty) {
                var i = 0;
                for (var key in netasParty) {
                    $scope.data1.dataTable.addRow([key.toString(), netasParty[key]]);
                    i++;
                    if (i > 20) break;
                }
            });
        });
        $scope.dataAll = $scope.data1;
       //sample data
        $scope.data2 = {};
        $scope.data2.dataTable = new google.visualization.DataTable();
        $scope.data2.dataTable.addColumn("string", "Name");
        $scope.data2.dataTable.addColumn("number", "Qty");
        $scope.data2.dataTable.addRow(["Test", 1]);
        $scope.data2.dataTable.addRow(["Test2", 2]);
        $scope.data2.dataTable.addRow(["Test3", 3]);
    }
]);

服务

'use strict';

myNetaInfoApp.factory('allCandidates2009Svc', ['$http', '$q',
    function ($http, $q) {
        var netas;
        return {
            GetPartyCriminalCount: function () {
                var deferred = $q.defer();
                $http.get('../../data/AllCandidates2009.json')
              .then(function (res) {
                  netas = res;
                  if (netas) {
                      var finalObj = {};
                      _.each(netas.data, function(neta) {
                           finalObj[neta.pty] = finalObj[neta.pty] ? finalObj[neta.pty] + 1 : 1;
                      });

                      deferred.resolve(finalObj);
                  }
              });
                return deferred.promise;
            }
        };
    }]);

指令

"use strict";

var googleChart = googleChart || angular.module("googleChart", []);

googleChart.directive("googleChart", function () {
    return {
        restrict: "A",
        link: function ($scope, $elem, $attr) {
            var dt = $scope[$attr.ngModel].dataTable;

            var options = {};
            if ($scope[$attr.ngModel].title)
                options.title = $scope[$attr.ngModel].title;

            var googleChart = new google.visualization[$attr.googleChart]($elem[0]);
            $scope.$watch($attr.ngModel, function (oldval, newval) {

                googleChart.draw(dt, options);
            });

        }
    };
});

HTML

<div ng-controller="allCandidatesController">
    <div class="col-lg-6">
        <h2>Parties and Candidates with Criminal Charges</h2>
        <div google-chart="PieChart" ng-model="dataAll" class="bigGraph"></div>
        <!--<p><a class="btn btn-primary" href="#" role="button">View details &raquo;</a></p>-->
    </div>

   <div class="col-lg-6">
        <h2>Heading</h2>
        <div google-chart="BarChart" ng-model="data2" class="bigGraph"></div>
    </div>

</div>

1 个答案:

答案 0 :(得分:0)

我认为您需要使用allCandidates2009Svc将您的函数体包装在scope.$apply()工厂中。但返回deferred.resolve()将在scope.$apply()之外。

function asyncGreet(name) {
var deferred = $q.defer();

setTimeout(function() {
// since this fn executes async in a future turn of the event loop, we need to wrap
// our code into an $apply call so that the model changes are properly observed.
scope.$apply(function() {
deferred.notify('About to greet ' + name + '.');

if (okToGreet(name)) {
deferred.resolve('Hello, ' + name + '!');
} else {
deferred.reject('Greeting ' + name + ' is not allowed.');
}
});
}, 1000);

return deferred.promise;
}

阅读此处的文档

http://docs.angularjs.org/api/ng.$q