-->

AngularJS & D3 : Angular directive for D3 load mul

2019-08-15 03:44发布

问题:

I wrote an angular directive for d3 forced-directed graph. Code is here. I use $log.log("xx"); to debug the code. I realized for some reasone this directive load multiple times. For the mg-controller, the one the directive bond with, I have 2 factories and these two factories are called whenever the controller is initialized. By using $log.log("xx"); I realized when the pay is loaded, the d3 directive at least load 6 times, twice for each factory and twice after. The way I "got around" is using d3.select("svg") .remove(); so my page won't have duplicates svgs. But this highly affects the performance. Beside, I added some costumed filter in the same page under the same controller, and I noticed whenever the filter runs, the d3 directive will reload. The filter has not thing to do with the d3 directive, except they are under the same controller.(I don't think the controller reload when the filter runs.)

I believe the issue is in my link: function part. It seems messy but it actually only does two things: 1) generates data the will be feed to d3 2)do some d3 and generates the graph.

template:'<div>{{fdg()}}<div>',
            link: function ( $scope, $element,attr){
                             ...
                        $scope.fdg = function(){
                            $log.log("in function");
                            $scope.getLinks();
                            ForceDirectedGraph($scope.tags,$scope.links);
                        }

I put two functions into $scope.fdg and invoke it in template:'<div>{{fdg()}}<div>'. This is probably a very bad practice, but I couldn't figure out other ways to invoke the function.

I tried to invoke these two functions

 $scope.getLinks();
 ForceDirectedGraph($scope.tags,$scope.links);

Directly in the link: function like this:

link: function ( $scope, $element,attr){
                            $log.log($scope.tags);
                            $log.log(tags);
                            $scope.getLinks();
                            ForceDirectedGraph($scope.tags,$scope.links);

Strangely, $scope.tags is empyty, "[]" and 'tags' is undefined. I passed 'tags' in view by <forcedirected-graph tags="tags" style="overflow: hidden;"></forcedirected-graph> I truly could not understand why the function could not get the argument. That's why I stupidly use $scope.fdg.function()... to wrap these two functions so they could reach to the argument passed from view.

I have some other (d3) directives that loads normally. I try to make the template of the abnormal d3 directive to match those working directives, but I failed :( (I am confused by how arguments/scope actually works in directive link).

More completed codes: here and here.

It will be great if I could figure out what's wrong so I could gain a deeper understanding in Angular. Angular is really awesome :)

Thanks in advance!

回答1:

Are you using an ng-repeat somewhere?
I remember realising that the link-function get´s executed multiple times for each element in the ng-repeat. So maybe in this case it´s better to use the compile function instead. Check this article: http://www.jvandemo.com/the-nitty-gritty-of-compile-and-link-functions-inside-angularjs-directives/