我正在尝试使用Angular指令创建d3图表。我设法创建它,但问题是我想在图表元素上有一些ng-click事件,我不确定应该怎么做。
这是我的指示:
.directive('circleChart', function($parse, $window, $compile) {
return {
restrict: 'A',
scope: {
datajson: '='
},
link: function(scope, elem, attrs) {
var circleChart = new CircleChart(scope.datajson);
circleChart.initialise(scope);
var svg = circleChart.generateGraph();
svg = angular.element(svg);
console.log(svg);
//scope.$apply(function() {
var content = $compile(svg)(scope);
elem.append(content);
//});
}
}
});
CircleChart对象创建了我的d3图表,并且有一个地方我将ng-click属性附加到图表元素(似乎不是一个正确的Angular方式):
var CircleChart = Class.create({
initialise: function(scope) {
this.datajson = scope.datajson;
},
generateGraph: function() {
.............
var chartContent = d3.select("div#chart-content");
var svg = chartContent.append("svg")
.attr("id", "circle")
.attr("width", diameter)
.attr("height", diameter)
.style("border-radius", "50px")
.append("g")
.attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");
...............
var circle = svg.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("class", function(d) {
return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root";
})
.attr("id", function(d) {
return d.id;
})
.attr("value", function(d) {
return d.name
})
.attr("parent", function(d) {
if (d.parent) return d.parent['id']
})
.attr("ng-click", function(d) {
return "getEgs('" + d.id + "')";
})
...............
d3代码工作正常,因为如果从指令中删除编译代码,则会绘制图表,但不会触发ng-clicks。
如果我把编译代码留在那里,它会进入一个无限循环,浏览器正在构建内存,直到我不得不杀死它。
显然,我的方法不起作用,如果有人可以帮助我,那将会很棒。
答案 0 :(得分:5)
由于您正在CircleChart.generateGraph
内修改DOM并在编译后重新附加元素的内容:elem.append(content)
,您(可能)最终会进入无限循环。< / p>
如果您确实想要编译由此产生的模板,您可以简单地调用$compile(elem.contents())(scope);
,而无需再次使用clear
和append
内容。 $compile
将在DOM 就地上使用Angular魔法。
但是,正如我在评论中所建议的那样,由于您可以访问CircleChart
中的整个范围(我认为这可能是一种矫枉过正),您应该在d3
中捕获点击事件,从代码中调用getErgs
函数而不是$compile
- 代码并将任务委托给Angular。