将自定义事件添加到指令

时间:2014-05-13 23:56:47

标签: angularjs angularjs-directive

我有一个自定义指令,可以创建一个字段作为更大表单的一部分。大大简化,它看起来像这样:

.directive('entityField', function () {
    return {
        restrict: 'E',
        scope: {
            field: '=',
            attributes: '=',
            editMode: '='
        },
        templateUrl: '<input ng-blur="blur()" type="text"/>',

        link: function (scope, element, attrs) {
            scope.blur = function() {
                // call out to event listeners that blur event happened
            }
        }
    };
});

我的目标是让指令触发一个关于其输入元素模糊的事件,以便周围的控制器可以处理模糊事件并执行一些复杂的验证。

那么,如何在指令中引发一个事件,以便周围的控制器可以监听它呢?

1 个答案:

答案 0 :(得分:3)

如果您没有使用隔离范围,可以使用$emit将事件发送到控制器的范围。但是,由于 使用隔离范围,因此您的指令不会从父控制器的范围继承,这使得此方法无法实现。

相反,您可以使用$broadcast中的$rootScope方法将范围原型链中的事件发送到控制器:

<强>指令:

.directive('entityField', function ($rootScope) {
    return {
        restrict: 'E',
        scope: {
            field: '=',
            attributes: '=',
            editMode: '='
        },
        templateUrl: '<input ng-blur="blur()" type="text"/>',

        link: function (scope, element, attrs) {
            scope.blur = function() {
                $rootScope.$broadcast('blur');
            }
        }
    };
});

然后使用$on在控制器中捕获它:

<强>控制器:

.controller('MyController', function($scope){
    $scope.$on('blur', function(){
        //react to event
    })
});

希望这是对您问题的最狭隘解释的充分答案。我还想提一下,通常使用范围和/或服务的原型性质来进行交叉指令/控制器通信会更好。我今天对另一个问题的回答有助于涵盖这个主题:How to call controller function from directive?