Presenter First is a pattern often used at Atomic. It allows you to drive your development from the business logic down. We recently tried this approach on our project in Backbone.js using CoffeeScript.
With a few helpers, our presenter tests are simple to write and our models and views are nice and separated. We’ve also been pulling out our template expansion into a separate class. Instead of the standard Presenter First triplets we have quads: Presenters, Models, Views, and Expanders. Here’s a small example of how we use our Presenters:
We use Backbone’s built in events for wiring up the business logic.
namespace "MyWidget", (exports) ->
class exports.Presenter
constructor: (@view, @model) ->
@view.bind "openClicked", =>
@view.showLoading()
@model.reload()
@model.bind "reloaded", =>
@view.render @model
In this example, we’re just using a standard Backbone model. We often have view-models that are composed of Backbone models.
namespace "MyWidget", (exports) ->
class exports.Model extends Backbone.Model
reload: =>
@fetch
success: =>
@trigger "reloaded"
We have a very thin view that is in charge of DOM manipulation and event binding.
namespace "MyWidget", (exports) ->
class exports.View extends Backbone.View
events:
"click .open": "openClicked"
"click .save": "saveClicked"
openClicked: =>
@trigger "openClicked"
saveClicked: =>
@trigger "saveClicked"
render: (model) =>
$(@el).html(MyWidget.Expander.expand(model))
showLoading: =>
# code for loading, turn on spinner, hide other stuff etc
The Expander is in charge of mapping data from our model to the jquery-expand directive.
namespace "MyWidget.Expander", (exports) ->
template = JST["thingers/widget"]
exports.expand = (model) ->
template({
'$.name': "#{model.get('first_name')} #{model.get('last_name')}"
})
So there you have it: Presenter First in Backbone.js using CoffeeScript.
Shawn,
I really enjoyed reading through your blog posts, and was wondering if you would be interested in having some of your content featured on DZone.com. If so, please contact me for more info.
Thanks!
Chris