2

I have read many SO answer but couldn't resolve the problem.

I have a Javascript function that create HTML element like document.createElement(...)

This is a part of that function :

var div=document.getElementById(params.wrapper);
div.setAttribute("ng-controller","ProjectController");

var button = document.createElement('button');
button.setAttribute('id','btn-view-users-' + params.id);
button.className='button-manage-user';
button.setAttribute('ng-click','hello()');
div.appendChild(button);

This function is called at the start of the application and create many rows so when the page is loaded the HTML generated by the function look like this : (this sample code is simplified to be more comprehensible)

<div id="wrapper" class="wrapper ng-scope" ng-controller="ProjectController">
    <button id="btn-view-users-310" class="button-manage-user" ng-click="hello()">Manage Users</button>
    <button id="btn-view-users-311" class="button-manage-user" ng-click="hello()">Manage Users</button>
    <button id="btn-view-users-312" class="button-manage-user" ng-click="hello()">Manage Users</button>
    <button id="btn-view-users-313" class="button-manage-user" ng-click="hello()">Manage Users</button>
</div>

The Angular controller :

app.controller('ProjectController',
    ['$scope', '$http',
        function($scope, $http) {
             $scope.hello = function(){
                console.log("hello")
             }
        }
    ]
)

At the end of the function when all elements are created I compile with :

var content = $(".wrapper");
angular.element(document).injector().invoke(function($compile) {
    var scope = angular.element(content).scope();
    $compile(content)(scope);
    console.log("#compile")//log appears in the console 10 times if 10 elements are created.
});

But when I click on the button the "hello" is fired many times !

If I have 10 elements on the page and click on the first element it is fire 10 times, if I click on the second element it is fired 9 times and so on..

I have tried to move the ng-controller declaration inside the button button.setAttribute("ng-controller","ProjectController"); Or even in the <body> tag but I still get the same behavior.

Thanks for you help

Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
Merlin
  • 4,907
  • 2
  • 33
  • 51

1 Answers1

2

Its because you are compiling the controller div, Which will do compile ng-controller="ProjectController" directive and will register instance of your ProjectController as many times you compile the div.

You should do $compile(content.contents())(scope); instead of compiling whole controller element.

But compile element should have only one root element like in your case you can not do that, because element which you wanted to compile should have exact one root element. Other should be child element of that root.

Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
  • Actually there is more div imbricated in my code. The example I gave is simplified. What you are saying is I should compile the ng-controller definition child div? – Merlin Sep 09 '15 at 15:56
  • @Lorenzo yes..but in your you need to change bit structure.. do look at edit – Pankaj Parkar Sep 09 '15 at 16:02
  • I cannot post the entire code its a way to big! Could you explain where I'm supposed to declare the ´ng-controller´ and which part I am supposed to ´compile´. Should I complie the part where the ng-controller is declared ? Could you provide a small example please ? If compile the ng-controller's child div the ng-click is not firing... Thank you – Merlin Sep 09 '15 at 16:13
  • @Lorenzo can I know when you are calling the the code by which you are compiling element.. – Pankaj Parkar Sep 09 '15 at 16:19
  • Inside the function that create the elements. At the end of the function. And this function is called many times... it might be the problem – Merlin Sep 09 '15 at 16:24
  • Thanks for you help you get me on the right direction. Problem is solved! – Merlin Sep 09 '15 at 16:38
  • @Lorenzo Glad to help you..basically you need to compile `ng-controller` once...other time you just need to compile its child.. – Pankaj Parkar Sep 09 '15 at 18:56