JSFiddle - React, Tailwind, and code Playground

HTML

<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<div ng-app="treeModule" ng-controller="TreelistController">
<tm-tree src="categories" fetch-children="fetchChildren()" select-node="toggleTree(node)"></tm-tree>
</div>

CSS

.treeNode {
  min-height: 40px;
  line-height: 40px;
   font-size: 12px;
  display:block;
}
.node {
  display: inline-block;
  border-bottom: 1px solid #e6e6e6; 
}
.wholerow {
  width: 100%;
  cursor: pointer;
  position: absolute;
  left: 0;
  border-bottom: 1px solid #e6e6e6; 
}

ul {
  list-style-type: none;
  padding-left:20px;
    
  lis:before {
     content: "\e114";
     display: inline-block;
      font-family: 'Glyphicons Halflings';
  font-weight: 400;
  position: relative;
  font-size: 10px;
  display: inline-block;
 
     width: 10px;
  }    
}
.collapsed ul {
  display: none;
}


li.collapseds:before {

  content: "\e080";
  font-family: 'Glyphicons Halflings';
  font-weight: 400;
  position: relative;
  font-size: 10px;
  display: inline-block;
  width: 10px;
}  
li a:hover {
  cursor: pointer;
}

JavaScript

var treeModule = angular.module('treeModule', []);

treeModule.directive('tmTree', function() {
  return {
    restrict: 'E', // tells Angular to apply this to only html tag that is <tree>
    replace: true, // tells Angular to replace <tree> by the whole template
    scope: {
      t: '=src',
      fetchChildren: '&fetchChildren',
      selectNode : '&selectNode' // create an isolated scope variable 't' and pass 'src' to it.  
      
    },    
    controller : function($scope){
      console.log('aaa');
     
    },
      template: '<ul><branch ng-repeat="c in t.children" src="c" fetch-children="fetchChildren()" select-Node="selectNode({node :child})"   ng-class="c.expandChildren ? \'\':\'collapsed\' "></branch></ul>' ,
    link: function(scope, element, attrs) {
      
    }   
  };
});

treeModule.directive('branch', function($compile) {
  return {
    restrict: 'E', // tells Angular to apply this to only html tag that is <branch>
    replace: true, // tells Angular to replace <branch> by the whole template
    scope: {
      b: '=src',
      fetchChildren: '&fetchChildren', // create an isolated scope variable 'b' and pass 'src' to it.  
      selectNode : '&selectNode'
    },
    controller : function($scope,$element){
      
    } ,   
      template: '<li class="treeNode"><div class="wholerow"></div><span id="chevron-right" class="glyphicon glyphicon-chevron-right" ></span><a ng-click="selectNode({child : b})">{{ b.text }}</a></li>',
    link: function(scope, element, attrs) {
      //// Check if there are any children, otherwise we'll have infinite execution
      
      var has_children = angular.isArray(scope.b.children);
      var parent = scope.b;
      //// Manipulate HTML in DOM
      if (has_children) {        
          element.append($compile( '<tm-tree src="b" fetch-children="fetchChildren()" select-Node="selectNode({node:child})" ></tm-tree>')(scope) );
        
        // recompile Angular because of manual appending
       ...