oosniss oosniss - 6 months ago 169
Javascript Question

Adding an Angular custom directive to dynamically generated DOM?

I am using a JavaScript library called "Treant.js" to dynamically generate a tree structure.

Because the DOM elements responsible for the tree structure are dynamically generated as SVG by the Treant.js library, I do not have direct access to those elements at all.

Here is what the HTML looks like

<div class="node nodeBranches>
<p class="node-name>TEXT</p>
</div>


This block of codes gets added to the tree DOM whenever a new data is added via form.

Here is the code that I came up with in order to add "ng-class" directive to the div whose class is node.

var target = angular.element(".nodeBranches");
for (var i = 0; i < target.length; i++) {
target.eq(i).attr("ng-class", "changeClass()");
}


Looking at the developer's tool in chrome, I see that the custom attribute "ng-class" is added to each div.node, but the functionality is not there.

The same thing happens for "ng-click" attribute as well. I can see the custom directive in the code, but it does not work.

How can I make this work using AngularJS?

Answer

By $compile. Document here.

And an example, help it works.

angular.module('app', [])
  .controller('appCtrl', function($scope) {

  })
  .directive('ngAddClass', function($compile) {
    return {
      restirct: 'AE',
      link: function(scope, ele, attrs) {

        scope.changeClass = function() {
          console.info('red');
          return 'red';
        }

        var target = angular.element(".nodeBranches");
        for (var i = 0; i < target.length; i++) {
          target.eq(i).attr("ng-class", "changeClass()");
          $compile(target)(scope);
        }
      }
    }
  });
.red {
  color: red;
}
<script src="//cdn.bootcss.com/jquery/2.0.0/jquery.js"></script>
<script src="//cdn.bootcss.com/angular.js/1.4.7/angular.min.js"></script>
<div ng-app="app">
  <div ng-controller="appCtrl">
    <div ng-add-class>
      <div class="node nodeBranches">
        <p class=" node-name">TEXT</p>
      </div>
    </div>
  </div>
</div>