3

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.

dcodesmith
  • 9,590
  • 4
  • 36
  • 40
Bas Slagter
  • 9,831
  • 7
  • 47
  • 78
  • 2
    I put everything in the controller so it is all in one place. I read somewhere recently that link should now be avoided but I can't find the source. This is a personal opinion but you did ask for thoughts. :-) – camden_kid Apr 10 '15 at 12:37

2 Answers2

2

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.

null
  • 7,906
  • 3
  • 36
  • 37
  • Yes, of course the actual code I'm working on is a bit more complex so thinking about this will really show it's efforts in the end. I think I'll stick with the link approach then. Thanks – Bas Slagter Apr 10 '15 at 13:04
1

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

Community
  • 1
  • 1
v1vendi
  • 603
  • 4
  • 9