1

So, I've been talking with co-workers about the "right way" to create an AngularJS controller. I know there are several ways of creating one, but I'm interested in getting my team writing them the same way AND the "right" way. By "right way" I'm talking about easy to read, testable, and performant. I'm sure there are competing theories on the best way to create a controller, but I'm most interested in test-ability at the end of the day since that is what AngularJS is built to do well.

Without further ado, here's the contenders:

Let's assume that our app is declared as so: var app = angular.module('app',[]);

1.

app.controller('myCtrl', function(){
  ...
});

2.

function myCtrl = {
  ...
}
app.controller('Ctrl', myCtrl);

3.

(function(app) {
  app.controller('myCtrl', function() {
    ...
  }
})(app);

Please let me know if I've missed one.

This does not take into consideration the changes needed for minification so please do not add that to this conversation.

Thanks! (I hope this doesn't start a flame war ><)

dganoff
  • 43
  • 1
  • 4

3 Answers3

1

My team exclusively uses 1. I've considered 3 as well, and we just have a standing rule (and jshint constraint) about global level code. I would never use 2.

Jeff Hubbard
  • 9,822
  • 3
  • 30
  • 28
1

I always do it this way:

angular.module('myModule').controller('MyController', ['$scope', function($scope) {

   <stuff>

}]);

Yes, it's a little more verbose, but it creates nothing in global scope, it is very clear what module the controller belongs to, and if I need to separate my controller into another file I just copy and past it without worrying about where 'app' is defined or about whether I missed a '.' in a chained declaration.

And I know I was supposed to ignore it, but of course this version is minification safe.

In general I believe you should find a clear standard and stick to it. That way if something doesn't look "right" you can tell right away.

Geoff Genz
  • 2,006
  • 17
  • 20
0

The Angular team recently posted a best practices guide so that might be a good place to start: http://blog.angularjs.org/2014/02/an-angularjs-style-guide-and-best.html. Also this presentation discusses some best practices on creating controllers: https://docs.google.com/presentation/d/1OgABsN24ZWN6Ugng-O8SjF7t0e3liQ9UN7hKdrCr0K8/present?pli=1&ueb=true&slide=id.p

If you were using number 2 you wouldn't really need app.controller('Ctrl', myCtrl);. You can reference a controller from ng-controller even if it isn't defined with module.controller(...)

You might want to also consider making your controller as much like "classes" as javascript will allow and using the 'controller as' syntax.

var myApp = angular.module("myApp", []);

myApp.MyCtrl = function($log) {
    this.$log = $log;
}

myApp.MyCtrl.prototype.sayHello = function() {
    this.$log('hello');
}

There are cases where it may be useful to have your controllers globally accessible. Like if you want to create an instance of your controller with $injector.instantiate() you need to have access to its constructor (although you could use the $controller service to accomplish the same goal using a string).

var myCtrl = $injector.instantiate(myApp.MyCtrl); //Works
var myCtrl2 = $injector.instantiate('MyCtrl'); //Doesn't Work

But if you don't have a specific use case for making your controllers global you should probably encapsulate them with module.controller(...);.

This answer also advocates using module.controller() https://stackoverflow.com/a/13363482/373655

Community
  • 1
  • 1
rob
  • 17,995
  • 12
  • 69
  • 94