通知控制器指令中所做的更改

Notify a controller for changes made in directive

我有一个指令如下:

(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'
        };
    }
})();

我从 view exemple-tree-view.html 调用这个指令如下:

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

此视图有一个名为 sampleTreeView 的控制器。

在我的指令中,addActionButtons 函数是从 init 函数调用的,而 init 函数本身是从指令的 link 函数调用的。

addActionButtons 函数中,我为指令的控制器范围声明了三个函数:scope.removeNodescope.renameNodescope.createNode,这些函数将执行一些 DOM 操作,并接收一个回调函数,该函数接收三个参数:nodesuccesscancelled,在这些函数中我想通知 sampleTreeView 控制器已进行更改,并将这三个参数传递给它,因此我可以使用这三个参数执行一些处理。

我该怎么做?

您可以为此使用 Angular 广播服务:

在指令中:

$rootScope.$broadcast('some-event', { any: {} });//pass params you want to pass

在控制器中:

 var deregister =  $rootScope.$on('some-event', function(event, args) {
        console.log(args)//passed params
    });

取消注册可以这样调用:

deregister();