Question

I have a custom directive that creates a field as part of a larger form. Vastly simplified, it looks like this:

.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
            }
        }
    };
});

My goal is to have the directive fire an event on blur of its input element so that the surrounding controller can handle the blur event and perform some complex validation.

So, how do I raise an event in a directive such that the surrounding controller can listen for it?

Était-ce utile?

La solution

If you weren't using isolated scope, you could use $emit to send the event up to the controller's scope. However, since you are using isolated scope, your directive does not inherit from the parent controller's scope, which makes this method impossible.

Instead, you can use the $broadcast method from $rootScope to send the event down the scope prototype chain to the controller:

Directive:

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

Then use $on to catch it in your controller:

Controller:

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

Hopefully this is a sufficient answer to the narrowest of interpretation of your question. I want to also mention that it is often better to use the prototypical nature of the scope and/or services for cross directive/controller communication. My answer to another question today helps to cover this topic: How to call controller function from directive?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top