Reputation: 26988
While creating AngularJS directives with CoffeeScript I was using this approach:
angular
.module('MyApp', [])
.directive 'myDirective', ->
restrict: 'E'
controllerAs: 'ctrl'
controller: ->
new class
constructor: ->
@value = 3
This code works with Angular 1.2.14—jsbin—but does not with 1.3.0—jsbin. I don't have any error in the console, simply it does nothing. It appears that the controller is an empty object.
Upvotes: 2
Views: 2018
Reputation: 31
I use a pattern for defining my controllers with coffeescript classes and attaching them to the directive (also defined in coffeescript) with controllerAs so I can access the class properties and methods in the template. I also defined the classes using the controller provider. This worked great in angular 1.2.15 but broke when I updated to 1.3.6.
After much debugging, I realized that angular was no longer automatically putting the object instance returned by the coffeescript class onto the scope. The fix is very simple: manually put the instantiated class object on the scope, as show below:
myModule.directive 'cePageHeader', ->
restrict: 'A'
templateUrl: 'shared/ce-page-header.tpl.html'
replace: true
scope: true
controller: 'CePageHeaderDirectiveCtrl as cePageHeaderDirCtrl'
cePageHeaderDirectiveModule.controller 'CePageHeaderDirectiveCtrl',
(UserModel, $scope) ->
$scope.cePageHeaderDirCtrl =
new class CePageHeaderDirectiveCtrl
constructor: ->
@user = UserModel
goHome: ->
console.log "Do something to go home"
Previously, the function simply returned the object created by the class. Adding this one line fixed the problem with 1.3.6:
$scope.cePageHeaderDirCtrl =
BTW, in the template I can access my class object like this:
<a class="navbar-brand" ng-click="cePageHeaderDirCtrl.goHome()">
Go Home
Without the manually assignment to the $scope, $scope.cePageHeaderDirCtrl = {}, an empty object.
Upvotes: 0
Reputation: 26988
I did some further research: it seems that in Angualar 1.3.0 if you use controllerAs
Angular will take controller
and execute new
on it. So this code fixes the problem:
angular
.module('MyApp', [])
.directive 'myDirective', ->
restrict: 'E'
controllerAs: 'ctrl'
controller: class
constructor: ->
@value = 3
Upvotes: 0
Reputation: 782
I answered almost the same question in this thread: AngularJS + Coffeescript - 'Hello World' directive not working. I like keeping my Angular objects as proper CoffeeScript classes. The key is to wrap the new Directive()
inside a function block.
class MyDirective
constructor: (myService) ->
// Constructor stuff
@controller = MyController
@controllerAs = 'ctrl'
restrict: 'E'
replace: true
scope:
attributeStuff: '='
link: (scope, element, attr) ->
angular.module('my_module').directive 'MyDirective', (myService) ->
new MyDirective(myService)
Upvotes: 5