简体   繁体   中英

Which parameters to pass into Angular JS custom directive controller?

I'm trying to create a custom directive which needs to use a separate controller because it needs to have functions which can be called by child directives.

Here is my code so far:

angular.module('myDirectives').controller('SlideInMenuController', function ($scope, $element, $attrs) {

    $scope.isOpen = false;

    // Toggle Function
    this.toggle = function(){

        $scope.$apply(function(){
            $scope.isOpen = !$scope.isOpen;
        });

    };


    // Watch $scope.isOpen and open the menu
    $scope.$watch('isOpen', function() {

        if($scope.isOpen == true){
            $element.attr('is-open', true);
        }
        else{
            $element.attr('is-open', false);
        }

        return false;

    });

}

angular.module('myDirectives').directive('slideInMenu', function ($swipe) {

    return {

        restrict: 'EA',
        scope: {},
        controller:'SlideInMenuController'        

    };

});


angular.module('myDirectives').directive('slideInMenuToggle', function ($swipe) {

    return {

        restrict: 'EA',
        require: '^slideInMenu',

        link: function ($scope, $element, $attrs, SlideInMenuCtrl) {

            $element.bind('click', function(){
                SlideInMenuCtrl.toggle();
            });

        }        

    };

});

(Note: I'm using ng-annotate so I don't have to write all my dependencies twice)

I need to inject the $swipe service into the directive controller but a normal controller would't have $scope, $element, $attrs as the first three parameters. This has made me wonder if I should be putting those into the link function instead and doing DOM stuff there, but if I do that what goes in the controller and what goes in to the link function.

I've read numerous blogs and SO answers that say what order compile/link/controller are run in but still can't find a clear answer as to whatin my above example should go where.

Any help would really be appreciated.

There are two kind of functions for AngularJS. Neither of which is intended to be called directly.

1) Injectables : functions that receive parameters, whose names must (with a few exceptions) be registered with dependency injection subsystem. It's the reason for ng-annotate to exist . You can also use array notation for these.

angular.module('stackOverflow').service('answer', ['myService', function(myService) {
...
}]);

Some examples are the ones you pass to angular.module() functions, like service() , factory() , directive() , controller() .

2) Plain functions . These have no special handling, it's vanilla JavaScript. They are passed to link and compile slots in directive definition objects.

You can omit rightmost parameters if you have no use for them, but not others. As the order of parameters is fixed, you cannot reorder them. But you can call them whatever you want .

That's it about functions.

About conventions using $ : beware! AngularJS builtin services are prefixed with $, so you should name parameters this way for injectable functions. For all other cases, don't prefix with $: your own functions and positional parameters like you see in link() and compile(). Prefix with $ in those functions is misleading and bad guidance .

To better distinguish parameters for compile() and link, you can prefix with t for template and i for instance. Nowadays I prefer to use those unprefixed. It's better for moving them around.

compile: function (tElement, tAttrs) {
    return function link(scope, iElement, iAttrs, ctrls) {
    };
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM