user2912840 user2912840 - 6 months ago 14
AngularJS Question

How To: Custom Code In An Angular Directive?

I have code that I wrote that makes donut charts. The JS I wrote has a function on it called "createChart" into which I can pass some JSON data and it will construct a donut chart in HTML from the data.. currently I just plop this into a provided target.

My thought is, if I can create a directive that has my custom code in it, and it returns the HTML for the donut, I can then assign this to the "template" in the directive and have it output that template HTML into my page.

The directive will need to consume data provided from a repeater or other binding in the page template.

Is there an easy way to do this and what are the proper functions to use in the directive ie: is it a .controller, or a .compile, or a .link?

Basically what I want is a directive that I can place all my chart code in, that consumes data potentially in a repeater (my page has rows of charts), and outputs the generated HTML into the page. Being able to use this in a repeater is key.

Here is what I want to do placed in the LINK function below:

app.directive("donut", function () {
return {
restrict: 'E',
template: '<div><b>{{donut.name}}</b></div>',
scope: {
donut: '='
},
replace: true,
//compile : compile,
link : link
};

function compile(){
console.log(donut)
}

function link(){
var html = '';
for(var x = 0 x < donut.values.length; x++){
html += '<b>' + values[x] + '</b>';
}
template = html;
}
});


here is what the final HTML should look like:

<svg id="svgTarget1" class="svg-target" width="100%" height="150" viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg" version="1.1" shape-rendering="geometricPrecision">
<path d=" M210,150 A60,60 0, 1,0 120.62400768209682,202.31683357523173 L110.83201024279576,219.75577810030896 A80,80 0, 1,1 230,150 z" fill="rgb(92,92,92)" stroke="rgb(92,92,92)" stroke-width="1"></path>
<path d=" M120.62400768209682,202.31683357523173 A60,60 0, 0,0 155.91452533214658,209.7077749551547 L157.88603377619543,229.6103666068729 A80,80 0, 0,1 110.83201024279576,219.75577810030896 z" fill="rgb(125,125,125)" stroke="rgb(125,125,125)" stroke-width="1"></path>
<path d=" M155.91452533214658,209.7077749551547 A60,60 0, 0,0 161.24287887514345,208.93723504372133 L164.99050516685793,228.5829800582951 A80,80 0, 0,1 157.88603377619543,229.6103666068729 z" fill="rgb(151,151,151)" stroke="rgb(151,151,151)" stroke-width="1"></path>
<path d=" M161.24287887514345,208.93723504372133 A60,60 0, 0,0 210,150.00000000000003 L230,150.00000000000003 A80,80 0, 0,1 164.99050516685793,228.5829800582951 z" fill="rgb(211,211,211)" stroke="rgb(211,211,211)" stroke-width="1"></path>
<path id="node0" d=" M109.58613592203994,80.95856613389196 L94.43093689280492,55.06802843410145 " stroke="rgb(211,211,211)" stroke-width="2"></path>
<path id="node1" d=" M133.6012676966216,228.30122335469693 L127.45174308285469,257.66418211270826 " stroke="rgb(211,211,211)" stroke-width="2"></path>
<path id="node2" d=" M161.44979865688956,229.1763986975708 L165.74347315322314,258.86754820915985 " stroke="rgb(211,211,211)" stroke-width="2"></path>
</svg>

Answer

The values you're passing are accessible through the scope object; that object needs to be passed to the directive functions you wish to work with:

app.directive("donut", function () {
return {
    restrict: 'E',
    template: '<div><b>{{donut.name}}</b></div>',
    scope: {
        donut: '='
    },
    replace: true,
    //compile : compile,
    link : link
};

function compile(){
    console.log(donut)
}

function link(scope){
    var html = '';
    for(var x = 0 x < scope.donut.values.length; x++){
        html += '<b>' + scope.donut.values[x] + '</b>';
    }