Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this function executed twice?

I've got a tree structure. JSBIN here

in the directive

scope.add_child_task = function() {
    scope.add_task(scope.path,"child of " + scope.member.name);
    if (!scope.has_children) {
        scope.add_children_element();
        scope.has_children = true;
    }
};

in the controller

$scope.add_task = function(to,name) { 
    DataFactory.add_task(to,name);
};

The factory is finding the correct position and adding the node.

When adding a child to nodes with existing children it's adding two children and i don't understand why.

Thanks.

EDIT I can lose has_children and it still produces the same result

updated JSBIN

Member link functin

link: function (scope, element, attrs) {            

            element.append("<collection></collection>"); 
            $compile(element.contents())(scope);

            scope.get_path = function() { 
                var temp = scope.$parent.get_path();
                temp.push(scope.member.name);
                return temp;
            };
            scope.path = scope.get_path();

            scope.add_child_task = function() {
                scope.add_task(scope.path,"child of " + scope.member.name);
            };
        }

EDIT 2 Droped the for loops as well - just exchanging references, nothing left but a function being executed twice !

updated JSBIN

like image 533
haki Avatar asked Dec 10 '13 14:12

haki


1 Answers

You're compiling the entire element (including the part added by the directive's template, which has already been compiled):

element.append("<collection></collection>"); 
$compile(element.contents())(scope);

Since your click handler is in the template compiling the template a second time results in a second set of click handlers (amongst other things) being added.

template: "<li>{{member.name}}" + 
      " <i>{{path}}</i> <a href ng-click='add_child_task()'>Add Child</a></li>",

The Fix: Instead use this to compile only the new element you've added:

newe = angular.element("<collection></collection>");
element.append(newe); 
$compile(newe)(scope);

updated jsbin

like image 152
KayakDave Avatar answered Sep 27 '22 01:09

KayakDave