A colleague found a guide, apparently from google here:
https://google-styleguide.googlecode.com/svn/trunk/angularjs-google-style.html
Reading this over, I have a few concerns based on my usage of angular of the last 6 months (I'm using Angular + Coffee in Rails, with the occasional Haml page):
- The doc seems to recommend using classes.
I've had a PITA dealing with code that relies on JS 'this' set to anything sane (which you'd leverage to invoke class method). This is especially painful in callbacks.
My work around was to make all my methods be tied to $scope, and ensure that all controller code resides in 1 lexical scope, e.g:
MyController = ($scope) ->
$scope.my_callback= ->
# do something useful, $scope is set to 'the right thing', and don't care about 'this'.
As opposed to the apparent recommendation of creating classes for controllers
class MyController
constructor: (@$scope) ->
callback: ->
# @ is in the hands of the caller...
The coffee->JS produces:
var MyController;
MyController = (function() {
function MyController($scope) {
this.$scope = $scope;
}
MyController.prototype.callback = function() {};
return MyController;
})();
Note that $scope is not in the lexical context of 'callback', which: a) means you have no hook to hang your hat on, and b) the coffeescript code is a bit confusing... if the method was not a class method, scope would have been in context :(
- Global names are promoted.
The doc seems to recommend using the google closure library goog.require/provide combo. While these are nice wrappers, they do effectively generate JS globals (with 'name spacing'). An alternative would be to wrap everything in a function (which in coffeescript land just involves putting things in a separate file), and only 'publish' the relevant items into angular as directives, services, controllers or what not. This avoids placing any globals into the JS namespace.
So... with all that said and done:
a) I can see controller == class being helpful in cases you have a controller class hierarchy, so you can use subclassing. But would you really do that? wouldn't you just factor out any common logic into a library or service. Is the pain around having 'this' ""float"" and not having '$scope' available worth it?
b) is there any reason to push controller/directive etc code into the global JS namespace?
(p.s not intending to star a religious war here, but I can live with that ;)