我在使用AngularJS(v1.2.5)服务调用填充的数据渲染Flotcharts时遇到问题。当数据是硬编码时,图表会按预期呈现,但不会在从$ resource调用中分配值时(控制台日志记录显示“undefined”作为值)。
奇怪的是,用于填充图表数据的相同变量显示在视图中并且工作正常,这使我认为这可能是某种竞争条件或范围问题。
我已经尝试分配$ scope变量作为已解决的promise的结果,但没有成功修复竞争条件以及尝试过诸如$ scope。$ apply()的图表指令。
以下是我的应用程序的代码摘录。任何帮助表示赞赏。谢谢。
HTML包装器:
<!DOCTYPE html>
<html data-ng-app="app" data-ng-controller="app">
<head>
<title>FlotChart Example</title>
</head>
<body>
<main data-ng-view></main>
</body>
</html>
概述路线中的模板:
<div class="chart-title">{{getCount.count}} Total Transactions</div>
<div id="deposits" data-chart="pie" data-flot-chart data-ng-model="model" data-ng-controller="OverviewCtrl"></div>
主要模块(“app”):
;(function (angular) {
'use strict';
angular.module('app', ['ngRoute', 'ngResource', 'ngTouch', 'services.Localization', 'Login', 'Overview'])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/login.html',
controller: 'LoginCtrl'
})
.when('/overview', {
templateUrl: 'views/overview.html',
controller: 'OverviewCtrl'
})
.otherwise({
redirectTo: '/'
});
}])
.controller('App', ['$rootScope', 'Localize', function ($rootScope, Localize) {
// initialize localization
$rootScope.labels = Localize.get();
}]);
}(angular));
概述控制器(用于图表和视图):
;(function (angular) {
'use strict';
angular.module('Overview', ['services.DepositsSvc'])
.controller('OverviewCtrl', ['$rootScope', '$scope', 'DepositCount', 'DepositCountGET', function ($rootScope, $scope, DepositCount, DepositCountGET) {
$scope.getCount = DepositCount.get();
$scope.getGETCount = DepositCountGET.get();
$scope.model = {};
$scope.model.data = [
{
label: $rootScope.labels.gets,
data: $scope.getGETCount.count,
color: "#e4d672"
},
{
label: $rootScope.labels.puts,
data: $scope.getCount.count,
color: "#c2cfeb"
}
];
$scope.model.options = {
series: {
pie: {
show: true,
radius: 1,
label: {
radius: 2/3,
formatter: function (label, series) {
return '<div class="pie">' + label + ': ' +
series.data[0][1] + '<br>(' + Math.round(series.percent) + '%)</div>';
}
}
}
},
legend: {
show: false
}
};
}]);
}(angular));
服务(两次通话的输出均为{count:number}):
;(function (angular) {
'use strict';
angular.module('services.DepositsSvc', ['ngResource', 'ngRoute'])
.factory('DepositCount', ['$resource', function ($resource) {
return $resource('/rest/deposits/count', {}, {
query: { method: 'GET', params: {}, isArray: true }
});
}])
.factory('DepositCountGET', ['$resource', function ($resource) {
return $resource('/rest/deposits/countgetdeposits', {}, {
query: { method: 'GET', params: {}, isArray: true }
});
}]);
}(angular));
图表指令:
;(function (angular, $) {
'use strict';
angular.module('directives.FlotCharts', [])
.directive('flotChart', function () {
return {
restrict: 'EA',
controller: ['$scope', '$attrs', function ($scope, $attrs) {
var plotid = '#' + $attrs.id,
model = $scope[$attrs.ngModel];
$scope.$watch('model', function (x) {
$.plot(plotid, x.data, x.options);
});
}]
};
});
}(angular, jQuery));
答案 0 :(得分:0)
您应该尝试将其提炼为适合jsFiddle的较小示例,以便我们可以尝试一下。
我注意到的一件事是,你正在做一个浅表,然后设置model.data和model.options。因此,除非我遗漏了某些东西,否则当手表发生变化时手表不会闪光;只有当模型本身发生变化尝试传递true
作为第三个要观察的参数。
答案 1 :(得分:0)
我不确定这会解决你的问题(因为这可能是很多问题的结果)但我认为你的指令范围和模型附件错了:
*。我不确定为什么你把这个指令封装成一个自调用函数(之前从未见过这种风格,当然不需要它。
*。您正在使用('directives.flotCharts',[])
语法在此处创建新模块,而没有[]
您可以将指令附加到任何现有模块。 重要的部分是这个模块没有注入app!您应该将它包含在app
模块依赖关系数组中。没有它,angular不知道这个指令(并且还包括index.html中的js文件......我有时会忘记并想知道为什么这不起作用)
*。我建议将指令重写为(并注意注释):
像这样的东西:
angular.module('directives.FlotCharts', []) // creaating a new module here
.directive('flotChart', function () {
return {o
restrict: 'EA',
scope:{model:"=ngModel"},//creating a two ways binding to ngModel
controller: ['$scope', '$attrs','$element', function ($scope, $attrs,$element) {
var plotid = '#' + $attrs.id, // you are doing an ugly hack instead of using $element, which comes with the directive, $element is a jquery (or jquery lite) object (if you included jQuery **before** angular.js in index.html it is a jQuery object)
$scope.$watch(function(){return $scope.model}, function (x) {
if (!x){
return;
}
$.plot(plotid, x.data, x.options);//may need to wrap this in an $apply, depends.. //surly this should be called on the $element object - something like: $element.plot(x.data, x.options) although I don't now the specifics of this lib.
}, true); //the true is needed for a deep equality and not just shallow check, which sometimes has problems with objects.. not sure you need this here.
}]
};
});
我也怀疑你对待承诺是错误的。但不确定这是否是这里的问题(虽然当其他一切都有效时,这可能会成为一个问题。对于这个答案和问题的范围,我认为你应该将承诺问题提炼到一个不同的具体问题。
祝你好运!答案 2 :(得分:0)
AngularJS Google Group记录的解决方案。