Having both a require and a controller in a directive

I’ve been playing around with AngularJS directives a lot recently trying to modularize out some commonly used bits of code – particularly form validation stuff. As part of this I often want a controller in the directive (so I have child scopes reach in and add elements or trigger events), but I also want to be able to access some parent angular things such as the ‘form’ directive’s controller.

Typically if you have a controller in a directive it gets passed in as the 4th argument to the link function eg:

angularApp.directive('ngValidSubmit', function() {
    return {
        controller: function($scope, $element, $attrs) {
        },
        link: function(scope, elem, attr, ngValidSubmitCtrl) {
        },
    }
});

However if you have a require argument it also gets passed in as the 4th element in link which unfortunately trumps our controller:

angularApp.directive('ngValidSubmit', function() {
    return {
        require: 'form',
        controller: function($scope, $element, $attrs) {
        },
        link: function(scope, elem, attr, formCtrl) {
        },
    }
});

I couldn’t find anything else referencing this problem on the internet, so as a hunch I tried (what turned out to be correct) multiple require arguments including requiring the directive itself:

angularApp.directive('ngValidSubmit', function() {
    return {
        require: [ 'form', 'ngValidSubmit' ],
        controller: function($scope, $element, $attrs) {
        },
        link: function(scope, elem, attr, ctrls) {
            var formCtrl = ctrls[0];
            var ngValidSubmitCtrl = ctrls[1];
        },
    }
});

Hopefully this helps someone!

Leave a Reply

Your email address will not be published. Required fields are marked *