ng-classify
Convert CoffeeScript classes to AngularJS modules
Write less JavaScript. Write less CoffeeScript. Write less Angular.Watch the screencast
Demo
Install
Install with npm
$ npm install ng-classify
Usage
CoffeeScript
ngClassify = require 'ng-classify' content = '''class Home extends Controller constructor: ($log) -> $log.info 'homeController instantiated'''' angularModule = ngClassify content
JavaScript
var ngClassify = ; var content = '\class Home extends Controller\n\ constructor: ($log) ->\n\ $log.info \'homeController instantiated\'\'; var angularModule = ;
Gulp
$ npm install gulp-ng-classify
Grunt
$ npm install grunt-ng-classify
Ruby Gem
ng_classify - maintained by pencilcheck
$ gem install ng_classify
Brunch
ng-classify-brunch - maintained by andrejd
$ npm install ng-classify-brunch
Table of Contents
Overview
AngularJS is well suited to take advantage of the CoffeeScript class syntax. However there's still a bit of boilerplate code we have to work through. ng-classify addresses this. Note: all examples are valid CoffeeScript.
Here's how you write a controller using ng-classify
: $scope.coolMethod = someServicecoolMethod
which is equivalent to
angular;
Why?
Take the following typical AngularJS controller declaration (same as above)
angular;
So what's wrong with this?
- App name,
angular.module('app').controller
, is required within the declaration- some avoid this by the use of a global variable,
app.controller
, which is not good JavaScript hygiene
- some avoid this by the use of a global variable,
- Parameter names are duplicated, one for the getters,
'$scope', 'someService'
, and one for the function parameters,function ($scope, someService)
- this duplication is required to make the module minifiable
- some avoid this by the use of ngmin
- Depending upon the desired naming format, module type (
controller
) and module name (adminController
) have duplication, due to the suffixedcontroller
in this example - The function is anonymous (unnamed), making it more difficult to debug
- Generally verbose
How?
Write AngularJS modules using the following syntaxes.
NOTE: {{}}
denotes placeholders
appName extends Animation|Config|Controller|Directive|Factory|Filter|Provider|Run|Service : # module body here
or
name extends App|Constant|Value : -> return value
CoffeeScript Classes
The typical way to use CoffeeScript classes with AngularJS is as follows.
# 203 characters : $scope.coolMethod = someServicecoolMethod angularmodule'app'controller 'adminController''$scope''someService'AdminController
which is equivalent to
// 177 charactersangular;
with ng-classify, this is all you need
# 116 characters : $scope.coolMethod = someServicecoolMethod
Benefits
- Removes unnecessary ceremonial code (
angular.module('app')
) - App name is not required when writing a module. It is now configurable.
- Parameters are needed only once via the
constructor
function. No need for the array syntax to make your code minifiable. - No need to suffix the module name with the module type, e.g. myController, myCtrl, etc.
- The function is named, making debugging more convenient
- The syntax is arguably concise. Bring your code to the forefront with the elimination of cruft.
Considerations
- To avoid the use of global variables, it is advised to use the
bare: false
CoffeeScript compilation option. see CoffeeScript Usage
Controller As Syntax
AngularJS provides two styles for writing and consuming controllers
$scope
this
withController as
$scope
example
: $scope.coolMethod = someServicecoolMethod
view for $scope
example
Cool It Down!
this
example
: @coolMethod = someServicecoolMethod
view for this
example
Cool It Down!
Module Types
App
Although there is no AngularJS App module type, it is included for consistency.
: -> return 'ngAnimate' 'ngRoute'
equivalent to
angular;
You may wish to use the then
CoffeeScript syntax to highlight your code even more by eliminating the need for extra lines of code and indentation, as follows. Note: this can be leveraged for any CoffeeScript class.
then : -> return 'ngAnimate' 'ngRoute'
Note: the app name is configured via the appName option, not the class name
Animation
: -> return : # run the animation here and call done when the animation is complete = # this (optional) function will be called when the animation # completes or when the animation is cancelled (the cancelled # flag will be set to true if cancelled).
equivalent to
angular;
Config
: $routeProvider when '/home' controller: 'homeController' templateUrl: 'home.html' when '/about' controller: 'aboutController' templateUrl: 'about.html' otherwise redirectTo: '/home'
equivalent to
angular;
Constant
: -> return '401': 'Unauthorized' '403': 'Forbidden' '404': 'Not Found'
equivalent to
angular;
Controller
The example below uses the this syntax
: = userServiceaddUser username
equivalent to
angular;
Directive
: -> return restrict: 'E' transclude: true templateUrl: 'dialog.html'
equivalent to
angular;
Factory
: return : $loginfo name
equivalent to
angular;
Another nice feature is the ability to return classes
: return : = -> " "
usage
user = 'Cary''Landholt'fullName = usergetFullName # Cary Landholt
Filter
: -> return "@"
equivalent to
angular;
Provider
: @name = 'default' = -> name = @name : -> $loginfo name = @name = name
equivalent to
angular;
Run
: $httpBackendwhenGET/^.*\.$/passThrough
equivalent to
angular;
Service
: = $loginfo name
equivalent to
angular;
Value
: -> return name: 'Luke Skywalker' age: 26 name: 'Han Solo' age: 35
equivalent to
angularvalue'people' name: 'Luke Skywalker' age: 26 name: 'Han Solo' age: 35 ;
Multiple Apps
Although using multiple apps in an AngularJS application is unnecessary, some may still wish to do so.
Simply provide the app name as a parameter to the module type.
In the example below, a Controller is created within the 'common' app.
'common' : $loginfo 'homeController instantiated'
equivalent to
angular;
API
ngClassify(content, options)
content
Required
Type: String
Default: undefined
The content that may contain CoffeeScript classes to convert to AngularJS modules
options
Type: Object
Default: undefined
options.appName
Type: String
Default: 'app'
The name of the AngularJS app
// for exampleangular
options.prefix
Type: String
Default: ''
To avoid potential collisions, the moduleType prefix may be set (ex: options.prefix = 'Ng'
)
: $loginfo 'homeController instantiated'
options.animation
Type: Object
Default: {format: 'spinalCase', prefix: '.'}
options.constant
Type: Object
Default: {format: 'screamingSnakeCase'}
options.controller
Type: Object
Default: {format: 'camelCase', suffix: 'Controller'}
options.directive
Type: Object
Default: {format: 'camelCase'}
options.factory
Type: Object
Default: {format: 'upperCamelCase'}
options.filter
Type: Object
Default: {format: 'camelCase'}
options.provider
Type: Object
Default: {format: 'camelCase', suffix: 'Provider'}
options.service
Type: Object
Default: {format: 'camelCase', suffix: 'Service'}
options.value
Type: Object
Default: {format: 'camelCase'}
Supported Formats
Format | Example |
---|---|
* | no change |
camelCase | camelCase |
lowerCamelCase | lowerCamelCase |
lowerCase | lowercase |
screamingSnakeCase | SCREAMING_SNAKE_CASE |
snakeCase | snake_case |
spinalCase | spinal-case |
trainCase | Train-Case |
upperCamelCase | UpperCamelCase |
upperCase | UPPERCASE |
Contributing
See CONTRIBUTING.md
Changelog
See CHANGELOG.md
License
See LICENSE