Notify a controller for changes made in directive

Viewed 554

I have a directive as following :

(function () {
    'use strict';

    angular.module('components.tree-component').directive('myTree', myTreeDirective);

    myTreeDirective.$inject = ['$http', '$compile', 'loggerFactory', '$q'];

    function myTreeDirective($http, $compile, loggerFactory, $q) {


        function addActionButtons(scope, element, attrs, tree) {
            var actionButtons = '<span class="action-button-container">' +
                '<md-button class="md-icon-button" aria-label="Nouveau" ng-click="createNode($event)">' +
                '<md-icon class="material-icons">add_circle</md-icon>' +
                '</md-button>' +
                '<md-button class="md-icon-button" aria-label="Modifier" ng-click="renameNode($event)">' +
                '<md-icon class="material-icons">edit</md-icon>' +
                '</md-button>' +
                '<md-button class="md-icon-button" aria-label="Supprimer" ng-click="removeNode($event)">' +
                '<md-icon class="material-icons">delete_circle</md-icon>' +
                '</md-button>' +
                '</span>';
            // foreach node that has actions set to true append action buttons to it's DOM
            for (var node in scope.config.core.data) {
                if (scope.config.core.data[node].actions === true) {
                    $(tree).find('#' + scope.config.core.data[node].id).find('a:first').after($compile(actionButtons)(scope));
                }
            }

            scope.removeNode = function ($event) {
                $(element).jstree(true).delete_node($($event.currentTarget)[0].closest('.jstree-node').id);
            };

            scope.renameNode = function ($event) {
                $(element).jstree(true).edit($($event.currentTarget)[0].closest('.jstree-node').id, '', function (node, success, cancelled) {
                    addActionButtons(scope, element, attrs, tree);

                });
            };

            scope.createNode = function ($event) {
                var sel = $(element).jstree(true).create_node($($event.currentTarget)[0].closest('.jstree-node').id);
                if (sel) {
                    $(element).jstree(true).edit(sel, '', function (node, success, cancelled) {
                        addActionButtons(scope, element, attrs, tree);
                    });
                }
            };

            scope.$apply();
        }


        function init(scope, element, attrs) {
            plugins(scope, element, attrs, scope.config);
            // resolve the added tree view
            var promise = $q(function (resolve, reject) {
                scope.tree = $(element).jstree(scope.config);
                resolve(scope.tree);
            });
            // if the tree has actions option set to true call that addActionButtons functions
            if (attrs.treeActions) {
                if (scope.treeActions === true) {
                    promise.then(function (tree) {
                        addActionButtons(scope, element, attrs, tree);
                    });
                }
            }
            events(scope, element, attrs);
        }

        /*
         * Link function
         */
        function linkFn(scope, element, attrs) {
            $(function () {

                if (attrs.treeCore) {
                    scope.config.core = $.extend(scope.config.core, scope[attrs.treeCore]);
                }

                scope.config.search.show_only_matches = attrs.treeFilterMode ? scope.treeFilterMode : false;
                scope.config.search.show_only_matches_children = attrs.treeFilterShowChildren ? scope.treeFilterShowChildren : false;

                // clean Case
                attrs.treeData = attrs.treeData ? attrs.treeData.toLowerCase() : '';
                attrs.treeSrc = attrs.treeSrc ? attrs.treeSrc.toLowerCase() : '';

                // source of data can be an html web page, a json file, an ajax call or a scope variable
                if (attrs.treeData === 'html') {
                    fetchResource(attrs.treeSrc, function (data) {
                        element.html(data);
                        init(scope, element, attrs);
                    });
                } else if (attrs.treeData === 'json') {
                    fetchResource(attrs.treeSrc, function (data) {
                        scope.config.core.data = data;
                        init(scope, element, attrs);
                    });
                } else if (attrs.treeData === 'scope') {
                    $(element).jstree('destroy');
                    init(scope, element, attrs);
                } else if (attrs.treeAjax) {
                    scope.config.core.data = {
                        'url': attrs.treeAjax,
                        'data': function (node) {
                            return {
                                'id': node.id !== '#' ? node.id : 1
                            };
                        }
                    };
                    init(scope, element, attrs);
                }
            });
        }

        // expose directive
        return {
            restrict: 'E',
            link: linkFn,
            scope: {
                ngModel: "=",
                treeTypes: "=treeTypes",
                treeEvents: "=treeEvents",
                treeFilterMode: "=treeFilterMode",
                treeFilterShowChildren: "=treeFilterShowChildren",
                treeActions: "=treeActions"
            },
            controller: function ($scope) {
                var vm = this;
                $scope.config = {};
                $scope.config.core = {};
                $scope.config.search = {};
                $scope.tree = {};
                vm.$onChanges = function () {
                    $scope.config.core.data = $scope.ngModel;
                };
            },
            controllerAs: 'vm'
        };
    }
})();

I call this directive from a view exemple-tree-view.html as following :

<my-tree tree-plugins="state" tree-actions="true"  ng-model="sampleTreeView.listNoeuds" tree-data="scope" />

This view has a controller called sampleTreeView.

In my directive, the addActionButtons function is called from the init function which by itself is called from the directive's link function.

In the addActionButtons function I have delared three functions for the directive's controller scope : scope.removeNode, scope.renameNode and scope.createNode, these functions will perform some DOM manipulation, and take in parameter a callback function wich receives three parameters : node, success, and cancelled, inside these functions I want to notify the sampleTreeView controller that changes has been made, and to pass those three parametres to it, so I can perform some treatement using those three parameters.

How can I do that ?

1 Answers
Related