Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
148
rated 0 times [  154] [ 6]  / answers: 1 / hits: 5766  / 10 Years ago, sat, march 22, 2014, 12:00:00

I am attempting to loop through an array and create multiple instances of a custom directive that creates different graphs based on some variables on the rootScope. Everything works fine except when I try to place those in a view and call ng-init to a method on the scope and pass it arguments.



What I am finding is that ng-init seems to run before anything (and I think ng-init is the wrong approach), which causes errors because the variables being set in the method aren't set yet when the ng-init runs in the view.



When I first load the index view, then go into this view, all is well, but when I try to load this view first or reload it, I am getting the errors. The ng-init is trying to call the chart() method before anything else runs.



On the index view, I have this chart in a modal that gets called onclick, so ng-init is not needed, therefore it works great.



I am a little stuck and what I need is advice on the right or better way to accomplish this.



On the detail view, I need to loop across that array to get four charts based on four different objects of data.



The data is a static file for now, as this is a prototype.



My code is essentially this:
View:



<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 method:



// 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 controller:



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


});


Service:



app.factory('ItemList', function($resource){
return $resource(/api/item-list.json);
});


Directive:



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

}
};
});


Edit:

I fixed this by removing the chart method altogether and replacing ng-init with attributes. Something like this:



<chart data-attrone=somedata data-attrtwo=some other data />


Then the attrs are available in the directive with attrs.attrone, etc.



Attribute names must be lower-case.



Hope this helps someone in the future.


More From » angularjs

 Answers
4

I fixed this by removing the chart method altogether and replacing ng-init with attributes. Something like this:



<chart data-attrone=somedata data-attrtwo=some other data />


Then the attrs are available in the directive with attrs.attrone, etc.



Attribute names must be lower-case.



Hope this helps someone in the future.


[#46623] Friday, March 21, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
beatrices

Total Points: 745
Total Questions: 103
Total Answers: 105

Location: Guam
Member since Tue, Nov 29, 2022
2 Years ago
;