Where to place click handlers using controllerAs syntax in directives

306 views Asked by At

When using the controllerAs syntax in AngularJS, what is the best place to define handlers for ng-click and such? On the controller or on the scope (defined in the link function)?

So, do you use:

angular.module('app', []).
    controller('myDirective', function(){
        return {
            template: '<div><button ng-click=vm.onClick()></button></div>',
            controller: function(){
                var vm = this;

                vm.onClick = function(){
                    vm.myValue = vm.doSomethingFancy();
                };

                this.doSomethingFancy = function(){};
            }
        }
    });

Or:

angular.module('app', []).
    controller('myDirective', function () {
        return {
            template: '<div><button ng-click=onClick()></button></div>',
            require: 'myDirecive',
            controller: function () {
                var vm = this;

                this.doSomethingFancy = function () {
                    vm.myValue = 'somethingfancy';
                };
            },
            link: function (scope, elem, attr, ctrl) {
                scope.onClick = function () {
                    ctrl.doSomethingFancy();
                }
            }
        }
    });

I actually like the second one because now the controller is only assigning values and event handling is done in the link function.

Anyway...let me know what your thoughts are.

2

There are 2 answers

1
null On

It's not all set-in-stone-rules, but you can use the following as a guidelines:

Separation of Concern

  • Modify model data in a controller
  • Modify the DOM/UI in the directive

Does doSomethingFancy do something fancy with your model (on the scope)? -- Go with the controller.

Does doSomethingFancy do something fancy with the user interface? -- Go with link

Race Conditions

  • Controller code is executed before template compilation
  • Link function is executed after template compilation

This isn't entirely true: you can also use the pre link method.

Common Sense

If you're code is more readably by placing a simple small function in the link method, use the link method. Over designing, just to comply with some rules isn't a good thing :) MV* patterns are guidelines.

0
v1vendi On

Long story short: there is no actual difference. Controller function runs earlier, but usually it doesn't matter. If your handlers don't have complicated logic, dependant on outer services - place them in link, otherwise - controller is better

Short story long: there is a similar question, that was answered with more detail:

Difference between the 'controller', 'link' and 'compile' functions when defining a directive