Getting Started with CoffeeScript

I've found CoffeeScript to be a great help when writing JavaScript. Since most of my future posts on Ext JS will probably be in CoffeeScript, I thought I'd explain the basics of how I use it.

The easiest way to start is to download and install Node.js. Then, install CoffeeScript by opening a command line and running:

npm install -g coffee-script
		

That's all there is to the installation. To use CoffeeScript, you can perform a manual build at the command line to generate the equivalent JavaScript. I won't even bother showing this, because that sort of manual process is definitely something I don't want to do. Happily, CoffeeScript includes a simple build system using a file called Cakefile. Here is a starter version of this file:

fs = require 'fs'

{print} = require 'util'
{spawn} = require 'child_process'

build = (callback) ->
  coffee = spawn 'coffee.cmd', ['-c', '-o', 'app', 'coffee']
  coffee.stderr.on 'data', (data) ->
    process.stderr.write data.toString()
  coffee.stdout.on 'data', (data) ->
    print data.toString()
  coffee.on 'exit', (code) ->
    callback?() if code is 0

task 'build', 'Build /app from /coffee', ->
  build()
		

Running cake build at the command line will recursively find any .coffee files in the folder /coffee and generate JavaScript in the folder /app. Obviously, you're free to change the folder names and paths as you need to.

So that's better, but still not ideal. I don't want to have to manually run cake build over and over. We can take things further by adding a watch command to the Cakefile:

fs = require 'fs'

{print} = require 'util'
{spawn} = require 'child_process'

build = (callback) ->
  coffee = spawn 'coffee.cmd', ['-c', '-o', 'app', 'coffee']
  coffee.stderr.on 'data', (data) ->
    process.stderr.write data.toString()
  coffee.stdout.on 'data', (data) ->
    print data.toString()
  coffee.on 'exit', (code) ->
    callback?() if code is 0

task 'build', 'Build /app from /coffee', ->
  build()
  
task 'watch', 'Watch /coffee for changes', ->
  console.log "Starting CoffeeScript compiler (watching for changes in /coffee folder)..."
  coffee = spawn 'coffee.cmd', ['-w', '-c', '-o', 'app', 'coffee']
  coffee.stderr.on 'data', (data) ->
    process.stderr.write data.toString()
  coffee.stdout.on 'data', (data) ->
    print data.toString()
		

Now, if we run cake watch, a directory watcher is created which will compile to JavaScript any time one of the .coffee files is changed! So you can just run this command, then mostly forget about it and get on with your work.

CoffeeScript is a very simple, straightforward language. I was off and running with it in less than a day. The CoffeeScript site has good documentation, and you can find additional info in the free online version of the Little Book on CoffeeScript.

Comments Comments (2) | del.ico.us del.icio.us | Digg It! Digg It! | Linking Blogs Linking Blogs | 8898 Views

Exploring ExtJS with DeftJS

It's been quiet here on Ye Olde Blogg lately. I've spent the last few months trying out various HTML component libraries and JavaScript frameworks, and have finally selected what I think is the most promising combination: ExtJS with DeftJS.

Anyone reading this is probably familiar with ExtJS, so I won't bore you with details on it. Suffice to say that its UI library rivals what is available in Flex, and indeed is better in many ways. (Data grids and trees, anyone?)

The main thing that initially bothered me about ExtJS was its MVC implementation. In my opinion it has a several flaws, one being the service locator approach. Another is that controllers use selectors that are relative to the application container to reference views, which isn't very flexible.

So I was pleased to see John Yanarella's contribution to the Sencha blog unveiling DeftJS. This is an extension to ExtJS which adds an inversion of control container and an improved controller tier through the use of ViewControllers.

I decided to try creating a DeftJS version of the car store example application that Sencha outlines in the documentation. What follows is a quick overview of the results.

Configuring the IoC portion of DeftJS is straightforward. Here, I'm specifying the two classes I want to add to the IoC container:

Ext.onReady( function () {
    Deft.Injector.configure({
        carChartJson: 'carStore.store.CarChartJson',
        carDataJson: 'carStore.store.CarDataJson'
    });
});
		

Next, I inject these into my view, and provide the ViewController class that I want to manage the view. This allows DeftJS to create the associated ViewController at the same time the view is created, and to destroy it when the view is destroyed.

Ext.define( 'carStore.view.CarListings', {
    extend: 'Ext.panel.Panel',
    mixins: [ 'Deft.mixin.Controllable', 'Deft.mixin.Injectable' ],
    inject: [ 'carChartJson', 'carDataJson' ],
    controller: 'carStore.controller.MyViewController',
...
		

Finally, my simple ViewController looks like this:

Ext.define( 'carStore.controller.MyViewController', {
    extend: 'Deft.mvc.ViewController',
    mixins: [ 'Deft.mixin.Injectable' ],
    inject: [ 'carChartJson', 'carDataJson' ],

    control: {
        carGrid: {
            selectionchange: 'onCarGridSelectionChange'
        },
        carDetail: true,
        carChartPanel: true
    },

    config: {
        carChartJson: null,
        carDataJson: null
    },

    onCarGridSelectionChange: function( selectionModel, selections ) {
        var carDataModel = selections[0];
        this.getCarDetail().update( carDataModel.getData() );
        this.getCarChartJson().loadData( carDataModel.getData().quality );
    }

});
		

I'm specifying the ID values (carGrid, carDetail, and carChartPanel) of the view elements I want to obtain references to. If necessary, a component query selector can also be used here. Note that unlike a standard ExtJS controller, these are relative to the view being managed rather than relative to the root application container. However, just like an ExtJS controller I can attach event listeners to the view instances. In this case, I'm handling the grid's selectionchange event to update the detail and chart views for their selected car. Essentially, this is an implementation of the Passive View design pattern.

That about covers the more interesting bits of this application. Since it's based on a very simple example, the rest of the code is pretty standard ExtJS. I've uploaded a running version of the app, and have pushed the source to GitHub for anyone who wants a deeper look.

DeftJS seems like a great extension to ExtJS. Not only that, but looking at the source also re-kindled my interest in Jasmine and CoffeeScript. The Jasmine specs for DeftJS are quite illuminating from a learning perspective, and the whole DeftJS framework is actually authored in CoffeeScript before being compiled out to JavaScript. I'll take a deeper look at both of these in upcoming blog entries.

Comments Comments (8) | del.ico.us del.icio.us | Digg It! Digg It! | Linking Blogs Linking Blogs | 25573 Views