Sunday, March 13, 2011

CoffeeScript + Backbone.js + Rails = Superfantasticalness

Lately I've been working on application by writing the front end in CoffeeScript using Backbone.js and the back end in Rails. A few people have asked me about it and so I thought I'd share my experience so far.

Backbone.js

I've been looking for a front end javascript framework for quite awhile, ever since I realized that server side MVC frameworks were probably coming to the end of their time in the sun.  I've even tried several aborted attempts to write one. I've spent good amounts of time playing around with both Sproutcore and JavascriptMVC, but when I picked up Backbone.js I didn't want to put it down again. I don't really want to spend the time right now to delve into critiques of the other two, so I'm going to focus on what I like about Backbone.js

For me, the big attraction of Backbone is there's so little to it.  Earlier in my career, I was enamored by frameworks and tools that did "everything I would ever need".  The idea of learning one environment where I could do everything was appealing.  I was attracted by neato whiz bang features even I didn't need them just yet.  But as I've grown older and more curmudgeonly, I now prefer tools that just barely do what I need and then stay out of the way.  In my mind pivotal tracker is such a tool.  Backbone.js  feels like this too.  It provides a nice structure for the code of a rich client web MVC application.  It allows me to continue to use html, css, and jquery without insisting that I give up one of these or do all my design and layout in javascript.  I prefer to work a designer who can create visually appealing UI in html/css, so frameworks that don't accomodate this workflow are a non-starter for me.

I don't intend this to be a Backbone.js guide, the excellent documentation is where to go for that.  But I'll briefly touch on my experience with the different pieces I've used thus far.

Views

The first Backbone code I wrote was a view.  I had started building my app in the usual (for me) way of just adding a some jquery to make my client side UI more dynamic.  But this time, when it started to get unmanagable as it always does, I refactored it into a Backbone View.  This is just a "class" that extends from Backbone.View.  The only thing this does for you is allow you to specify an element that the view contains, and a set of events scoped within this element that bind to functions of your view.  But it turns out this feels just right for organizing my code.  In my case I ended with a tree view component that uses jstree to do a lot of the heavy lifting.  Later on, I actually extracted it into a superclass and reused it on a couple other pages.  Over time I've found that my view classes tend to end up as nicely reusable components.

Interestingly, backbone views don't mandate any particular choice for producing the html.  After some experimentation, we came up with a convention we like on our project.  Each of our views generally has a template file, we're using mustache right now so the files are named things like foo_view.mustache.html.  Originally we were just embedding our templates into our rails views as hidden divs or in script tags.  But we found ourselves repeating the same markup in our jquery-jasmine fixtures, and this made us sad so we searched for a better way.  We settled on having templates in a separate file, and then wrote a rails helper method that renders the views template on the page.  We also wrote a jasmine jquery method that loads the template into a fixture so we can use them in our specs as well.  Here's what that code looks like, if anyone else wants it:


There are a couple of other things worth passing along we've learned working with Backbone views.  The first is that you really want to have your view's element have the same lifespan as your view object.  I ran into this issue by creating new view objects inside the listener method of another view.  There's nothing inherently wrong with this (that I know of), but in my case the element for the view I was creating already existed.  The net effect was that if if the listener method that created the view was called multiple times you could end up with a multiple views listening to events on the same DOM element.  This caused no end of confusion.  It was a much better idea to create the view once and just reuse-it as needed with different models (as necessary).

The other idea I feel like we're learning is how to communicate between models and views.  We regularly have views talk directly to models, getting and setting properties, telling models to persist themselves, etc.  But when it comes time for models to communicate with views, it really feels right to use the Backbone event framework.  There are a set of nice built in events on models, and it is trivial to add your own.  It's worked out well for models to trigger events when interesting things happen and let the views listen to them and do what they will.  So our best practice is shaping up that views can interact with models, including listening to events from them, but models should never talk to views directly.  It would probably seem obvious to do it this way for anyone coming from rails-land, but I thought it might be worth mentioning anyways.

Models

Backbone.js models know how to speak json to a restful back end out with little to no coding required.  This ended up being a pretty big selling point for me, as it made it trivially to integrate Backbone with my rails app and it pretty much Just Worked.  The only gotcha here is that rails would prefer to have the attributes for a model be grouped into a name parameter, but telling backbone to do this as as trivial as the following code:



I guess the biggest difference working with Backbone models than Rails models is that everything is asynchronous.  Calling a fetch (think find in rails) or a save in backbone means you also have to specify a function to invoke on success or failure, or listen to an event.  This would seem to add up to a lot of extra code, were it not for...

Coffeescript

I've been searching for Coffeescript without realizing it for many years.  I've been treating javascript as a first class language for a few years, test driving, trying to use clearly communicative object oriented design, etc.  This has made the experience of writing javascript immensely more satisfying, and I hope, helped me produce higher quality code.  But it's always chafed a bit.  I didn't get to choose javascript.  There's a lot of syntax is in it that I don't like, and feels noisier than I wish it was.  I spent a good amount of time looking for solutions to let me use a language of my choosing in the browser, but in the end they've all fallen short.

Until now.  Coffeescript is a lovely language that compiles into readable, debuggable, javascript.  It's documentation is fantastic and it's source code is beautifully documented.  The most annoying bits of javascript go away, and the coffescript code I've written is so much cleaner and less noisy it's been a joy to use.  I'm finding it difficult to convey how big a deal coffeescript is.  Someone smart I know responded to coffeescript allegedly by saying "But isn't it just nicer syntax?".  Yes it is!  And it turns out this is incredibly valuable and important.  I chose ruby because I can express my intent, in elegant, readable code.  Coffeescript feels the same way to me.  But I can use Coffeescript in all the places I would have had to use javascript before.  It's been huge to me.  I'm pretty much at the point where I'll go back to writing javascript when you pry Coffeescript from out of my hands.

Though I dig backbone a lot, it's still possible one of the other frameworks might mature into something awesome and be the way to go.  Coffeescript, on the other hand, doesn't appear to have anything close.

12 comments:

daauslander said...

You put an emphasis on "debuggable". Is there anyway that you know of for debugging Coffeescript besides stepping through the generated javascript line by line?

For me, step debugging is essential to my dev environment, and specifically stepping through the actual source. Do you have some method of stepping through the coffee script?

Mainster said...

Could you also please post the rails helper function you mention, to post the template output in your rails views? Thanks.

vi said...

I currently have a small project that uses coffee script and jstree and am looking to start using backbone.js to help me get my mess of scripting under control. As part of this, I was wondering if you had any example code you'd be willing to share that shows how you wrapped jstree in a view?

Thanks!

Brandon Fryslie said...

> Is there anyway that you know of for debugging Coffeescript besides stepping through the generated javascript line by line?

I would be very interested to find that as well. It doesn't seem to me to be possible using the current coffeescript compiler because it rewrites the code before compiling it. It takes 10+ over the token stream in all which I think would complicate writing an interpreter. :)

I'd keep my eye on this:
https://github.com/fab13n/parsec-coffee-script

but it doesn't seem to have a commit since Jan 2011. :(

xinag zhong said...

I would be Diablo 3 itemsvery interested to find that as well. It doesn't seem to me to be possible using the current coffeescript compiler because it rewrites the code before compiling it. It takes 10+ over the token stream in all which I think would complicate Cheapest wow goldwriting an interpreter. :)

Ming Zhang said...

The people today of ancient China think within the mandate of heaven. They worshiped several diverse gods Chinese Dress, which includes weather and sky gods in addition to a higher god who ruled all other gods identified as Shang Ti. Chinese as a race, worship their ancestors believing that when these died, they became gods too.

adeoe said...

You put an emphasis on "debuggable". Is there anyway that you know of for debugging Coffeescript besides stepping through the generated javascript line by line?

For me, step debugging is essential to my dev environment, and specifically stepping through the actual source. Do you have some method of stepping through the coffee script?gw2 gold

caton yesiondre said...

In addition there are speculations concerning windows 7 home premium product key what may very well be the key reason why at the rear of Microsoft is modern moves to office 2010 activation key< supply shoppers a drastic value slash for a few merchandise on the Microsoft Store.

AntoL-Nyo said...

HD kaliteli porno izle ve boşal.
Bayan porno izleme sitesi.
Bedava ve ücretsiz porno izle size gelsin.
Liseli kızların ve Türbanlı ateşli hatunların sikiş filmlerini izle.
Siyah karanlık odada porno yapan evli çift.
harika Duvar Kağıtları bunlar
tamamen ithal duvar kağıdı olanlar var

Vivian Salvatore said...

Diablo 3 Gold And finally, Intruders mustn't be supported in to a corner associated with varied simply fight while using shortbow Cheap GW2 Gold.

AntoL-Nyo said...

Ben istanbuldan selda 22 yaşında konfeksiyon içşisiyim Amatör Porno sizleri bekletmeden hemen hikayeme geçiyorum.. Biz 5 katlı bir binanın en üst katında yaşıyorduk ve bir öğlen paydosunda sevgilim beni Anal Sikiş aradı evdeydim çünkü evle iş yerim arasında 2 dakika bile yoktu.. Bende Asyalı Porno sevgilime benden telefon beklemesini söyledikten sonra evin durumuna baktım evde kardeşlerim ve annemin Esmer Porno birkaçtane arkadaşı vardı bu iş imkansızdı tekrardan düşündüm ve çatı katı aklıma geldi sevgilime telefon açıp çatıya çıkmasını ve Fantazi Porno beni beklemesini söyledikten sonra telefonu bir süre elime almadım anneme işe gidiyorum dedikten sonra Gay Porno hemen üst kata çatıya çıkıp sevgilimin
dudaklarına yumuldum az bir süremiz Götten Sikiş vardı ve çok istiyordum onu hemen önünde diz çöküp sikini çıkardım kocaman olmuştu bile... Özlemişti beni HD Porno bitanem başladım sikini yalamaya kafasını öpüyor onu çıldırtıyordum sevgilim saçlarımdan tutmuş ağzımı keyifle sikerken çatı katının kapısı açıldı toparlanamadan Lezbiyen Porno komşunun şişman oğlu efecan gelmişti ben dizlerimin üzerinde sevgilimin Liseli Porno siki ağzımda yakalanmıştım hemen bu halimizi gören komşu oğlu Sarışın Sikiş kaçarcasına gitti.. Sevgilim bir süre güldükten Türbanlı Porno sonra bu şişko neden kaçtı korktu herhalde onu sikicem sandı galiba dedikten sonra bir kahkaha daha attı ben sevgilimin Türk Porno sikine deli gibi saldırıyor yalıyor emiyordum boşalmasını istiyor Zenci Porno sütünü içmek istiyordum sevgilim ağzımı sike sike boşaldı hepsini yuttum bir damlasını ziyan Porno etmedim ve sevgilimle vedalaşıp ayrıldık... Ben her defasında sikiş yapmadan önce yazporno diye olan türkçe siteden Porno izle bölümüne girip seyrediyorum azdıktan sonra şahane sikiş ile gözleri kamaştırıyorum.

Jessica Colin said...

Do you mind if I quote a couple of your articles as long as I provide credit and sources back to your blog? My blog is in the very same area of interest as yours and my users would certainly benefit from some of the information you provide here. Please let me know if this alright with you. Thanks a lot!

dralihealth |

http://www.hondurastravelradio.com |

www.mahoneyssportscafe.com |

piedmontreal-estate.org |

sportscarrentalworld |

http://www.weddingsamui.org |

auto-corner.org |

businessresultimprovement |

http://www.coxlandscapingnj.com |

www.family-estate.org |