Skip to content

Instantly share code, notes, and snippets.

@elado
Last active January 28, 2017 08:43
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save elado/8138516 to your computer and use it in GitHub Desktop.
Save elado/8138516 to your computer and use it in GitHub Desktop.
Angular.js CoffeeScript Controller Base Class
# dependency - Function.prototype.bind or underscore/lodash
app = angular.module 'someApp'
class @BaseCtrl
@register: (app, name) ->
name ?= @name || @toString().match(/function\s*(.*?)\(/)?[1]
app.controller name, @
@inject: (args...) ->
@$inject = args
constructor: (args...) ->
for key, index in @constructor.$inject
@[key] = args[index]
for key, fn of @constructor.prototype
continue unless typeof fn is 'function'
continue if key in ['constructor', 'initialize'] or key[0] is '_'
@$scope[key] = fn.bind?(@) || _.bind(fn, @)
@initialize?()
app = angular.module 'someApp'
class BookFormCtrl extends BaseCtrl
@register app
# list of dependencies to be injected
# each will be glued to the instance of the controller as a property
# e.g. @$scope, @Book
@inject '$scope', 'Book'
# initialize the controller
initialize: ->
@$scope.book =
title: "Hello"
# automatically glued to the scope, with the controller instance as the context/this
# so usable as <form ng-submit="submit()">
# methods that start with an underscore are considered as private and won't be glued
submit: ->
@Book.post(@$scope.book).then =>
@$scope.book.title = ""
@zampino
Copy link

zampino commented Nov 10, 2014

very nice!

I would maybe prefer a "class method" declaration to indicate properties/methods to be exported to the scope.
Also, maybe in a previous spot, we could extend the main app module with the base class,
which already mentions the "app" we register the controller in.

class BookController extends MyApp.BaseController
  @register()
  @inject 'dep1', 'dep2'
  @scope_attr 'one', 'two', 'three'

  initialize: ->
    ...

But, as I said, very nice! 💥

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment