1

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?

1
  • Might be wrong, but replace link function with: controller: function($scope) { $scope.blur = function() {} } - not 100% if that'll work. Commented May 13, 2014 at 23:59

1 Answer 1

3

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?

Sign up to request clarification or add additional context in comments.

2 Comments

The directive above can be changed. Tomorrow, I'll try using isolated scope and $emit since that seems to be the most elegant way of doing what I need to.
$emit is working for me without any changes. Thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.