我试图遍历一个数组并创建一个自定义指令的多个实例,这些实例根据rootScope上的一些变量创建不同的图形。一切正常,除非我尝试将它们放在视图中并将ng-init调用到范围上的方法并传递参数。
我发现ng-init似乎在任何事情之前运行(并且我认为ng-init是错误的方法),这会导致错误,因为在方法中设置的变量尚未设置ng-init在视图中运行。
当我第一次加载索引视图时,然后进入此视图,一切都很好,但是当我尝试首先加载此视图或重新加载它时,我收到了错误。 ng-init试图在其他任何运行之前调用chart()方法。
在索引视图中,我将这个图表放在一个名为onclick的模态中,因此不需要ng-init,因此它工作得很好。
我有点陷入困境,我需要的是关于"权利"或更好的方法来实现这一目标。
在详细视图中,我需要遍历该数组以获得基于四个不同数据对象的四个图表。
现在数据是一个静态文件,因为这是一个原型。
我的代码基本上是这样的: 查看:
<div id="chart_list">
<div class="chart" ng-repeat="val in ['abc', 'def', 'ghi', 'jkl']" ng-init="chart('line', val, itemId, val)">
<h3>{{val | uppercase}}</h3>
<chart/>
</div>
</div>
AppController方法:
// get data set up for chart consumption
$scope.chart = function(chart, kpi, socId, chartId) {
$rootScope.visualize = {};
$rootScope.visualize.chart = chart;
$rootScope.visualize.chartId = chartId;
$rootScope.visualize.val = val;
$rootScope.visualize.item = $rootScope.itemList[itemId];
$rootScope.visualize.valName = $rootScope.visualize.item[val].name;
};
DetailView控制器:
app.controller('ItemDetailController', function($scope, $rootScope, $routeParams, ItemList) {
var itemId = $scope.itemId = $routeParams.itemId;
ItemList.get({}, function(res) {
$rootScope.itemList = res.data;
$scope.item = $rootScope.itemList[itemId];
});
});
服务:
app.factory('ItemList', function($resource){
return $resource("/api/item-list.json");
});
指令:
app.directive('chart', function() {
return {
restrict: 'E',
link: function(scope, element, attrs){
if ($(window).width() <= 1200){
var width = 300;
} else {
var width = 450;
}
var visualize = scope.visualize;
var data = visualize.soc[visualize.val].data;
var numTicks = Object.keys(data).length;
element.append('<div class="chart_container"><div id="y_axis' + visualize.chartId +'" class="y_axis"></div><div id="chart' + visualize.chartId + '" class="chart"></div><div id="x_axis' + visualize.chartId + '" class="x_axis"></div></div>');
element.append('<div id="legend_container' + visualize.chartId +'" class="legend_container"><div id="smoother' + visualize.chartId +'" title="Smoothing"></div><div id="legend' + visualize.chartId +'"></div></div>');
var valSeries = [];
var valSeries2 = [];
var valSeries3 = [];
var valMap = {};
var i = 0;
Object.keys(data).forEach(function(propertyName) {
var value = data[propertyName];
var val2 = (Math.random() * (102 - 87) + 86) / 100;
var val3 = (Math.random() * (95 - 70) + 69) / 100;
valSeries.push({x: i, y: data[propertyName].amount});
valSeries2.push({x: i, y: data[propertyName].amount * val2});
valSeries3.push({x: i, y: data[propertyName].amount * val3});
valMap[i] = data[propertyName].name;
i++;
});
var graph = new Rickshaw.Graph({
element: document.querySelector('#chart' + visualize.chartId),
width: width,
height: 150,
renderer: visualize.chart,
stroke: true,
series: [
{
data: valSeries3,
color: '#F0AD4E',
name: 'Three years ago',
},
{
data: valSeries2,
color: '#5BC0DE',
name: 'Two years ago',
},
{
data: valSeries,
color: '#5CB85C',
name: 'Past year'
}
]
});
var format = function(n) {
var map = valMap;
return map[n];
}
var x_ticks = new Rickshaw.Graph.Axis.X({
graph: graph,
width: width,
orientation: 'bottom',
element: document.getElementById('x_axis' + visualize.chartId),
pixelsPerTick: width/numTicks,
tickFormat: format
});
var y_axis = new Rickshaw.Graph.Axis.Y({
graph: graph,
orientation: 'left',
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
element: document.getElementById('y_axis' + visualize.chartId),
});
graph.render();
var hoverDetail = new Rickshaw.Graph.HoverDetail({
graph: graph,
formatter: function(series, x, y) {
var content = app.lib[visualize.dataFormat](parseInt(y)) + "<br>";
return content;
}
});
var legend = new Rickshaw.Graph.Legend( {
graph: graph,
element: document.getElementById('legend' + visualize.chartId)
} );
var shelving = new Rickshaw.Graph.Behavior.Series.Toggle( {
graph: graph,
legend: legend
} );
}
};
});
修改
我通过完全删除图表方法并用属性替换ng-init来解决这个问题。像这样:
<chart data-attrone="somedata" data-attrtwo="some other data" />
然后在指令中可以使用attrs.attrone
等来获取attrs。
属性名称必须小写。
希望这可以帮助将来的某个人。
答案 0 :(得分:1)
我通过完全删除图表方法并用属性替换ng-init来解决这个问题。像这样:
<chart data-attrone="somedata" data-attrtwo="some other data" />
然后,使用attrs.attrone
等指令中的attrs可用。
属性名称必须小写。
希望这有助于将来。