Занимаюсь разработкой веб-приложения. Столкнулся с необходимостью отображать древовидные данные. При беглом поиске в Google наткнулся на Angular Treeview. Свою задачу выполняет, но хотелось бы большей свободы при кастомизации элементов дерева.
Дальнейшие поиски ожидаемых результатов не дали. Вот так и появилось желание написать свой Treeview для AngularJS.

Html:
<div>
    <ul my-treeview>
        <li ng-repeat="item in items" my-treeview-childs="item.childrens">
            <span ng-click="say(item.id)" ng-class="{ bold: item.id % 2}">{{item.id}} {{item.name}}</span></li>
    </ul>
</div>




Javascript:
$scope.items = [
        { id: 1, name: 'First', childrens: [
            { id: 3, name: 'three', childrens: null },
            { id: 4, name: 'four', childrens: [
                { id: 5, name: 'five', childrens: null }
            ]
            }
        ]
        },
        { id: 2, name: 'second', childrens: [] }
    ];
$scope.say = function (str) {
        alert(str);
    }


Исходный код директивы:
var app = angular.module('myTreeview', []);

app.controller('myTreeviewCtrl', ['$scope', function ($scope) {

} ])

//объявляет дерево
app.directive('myTreeview', [function () {
    return {
        restrict: 'A',
        priority: 1001,
        controller: 'myTreeviewCtrl',
        compile: function (element, tAttrs) {
            //создаем шаблон для дочерних элементов
            angular.forEach(angular.element(element.find('li')), function (item) {
                var el = angular.element(item);

                el.prepend($('<i />').addClass('normal').attr('ng-hide', 'config.hasChildrens'));
                el.prepend($('<i />').addClass('expanded').attr('ng-show', 'config.hasChildrens && !config.collapsed').attr('ng-click', 'collapse(config)'));
                el.prepend($('<i />').addClass('collapsed').attr('ng-show', 'config.hasChildrens && config.collapsed').attr('ng-click', 'collapse(config)'));
            });

            var itemTemplate = element.html();
            var template = $('<ul ng-hide="config.collapsed" />').append(itemTemplate)[0].outerHTML;

            return function (scope, element, attrs, ctrl) {
                //делаем доступным шаблон для дочерней дерективы
                ctrl.Template = template;
                element.addClass('treeview');
                scope.collapse = function (config) {
                    config.collapsed = !config.collapsed;
                }

            }
        }
    }
} ])

//достраивает дочерние элемент
.directive('myTreeviewChilds', ['$compile', '$parse', function ($compile, $parse) {
    return {
        restrict: 'A',
        require: '^myTreeview',
        link: function (scope, element, attrs, ctrl) {
            //достаем дочерние элементы
            var items = $parse(attrs.myTreeviewChilds)(scope);
            var newScope = scope.$new();
            newScope.items = items
            scope.config = {};
            if (items != null && items.length > 0) {
                newScope.$parent.config.hasChildrens = true;
                newScope.$parent.config.collapsed = false;
                element.append($compile(ctrl.Template)(newScope));
            }
            else {
                newScope.$parent.config.hasChildrens = false;
                newScope.$parent.config.collapsed = false;
            }
        }
    }
} ])




Как видно из примера, программист сам контролирует шаблон элементов дерева, что дает большую гибкость при настройке представления.
При разработке были использованы материалы с http://angular.ru, http://angularjs.org и Angular Treeview(css и картинки). А так же вдохновением послужил пост пользователя esvit Директива для работы с таблицами на AngularJS. Надеюсь, кому-нибудь пригодится данное решение. Так же буду рад замечаниям и предложениям. Ссылка на исходники.
Спасибо за внимание.