ModelBinder in Coffeescript
HTML
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.modelbinder/0.1.3/Backbone.ModelBinder-min.js"></script>
<script src="https://raw.github.com/theironcook/Backbone.ModelBinder/master/Backbone.CollectionBinder.min.js"></script>
This is a simple example that shows how to use the ModelBinding with coffeescript. Futher, it shows how to update one data attribute in the model in multiple ways. In this example, changes to both sales and sales per square foot are stored in the sales attribute.<br/>
<br/>
Note, for a table with multiple rows, the CollectionBinder can efficently handle the same bindings for multiple rows.
<hr>
<div id="viewContent">
</div>
<script id="my-template" type="text/x-underscore-template">
<table id="sales_table" border="1" cellspacing="1" cellpadding="1" summary="table">
<thead>
<tr><th COLSPAN=4>Sales Table</th>
<tr>
<th>Year</th>
<th>Sales</th>
<th>Sales/PSF</th>
<th>GSF</th>
</tr></thead>
<tbody>
<tr>
<td name="year"></td>
<td><input type="text" name="sales"/></td>
<td><input type="text" name="sales_psf"/></td>
<td><input type="text" name="gsf"/></td>
</tr>
</tbody>
</table>
</script>
CSS
#sales_table td { text-align: center }
#sales_table th { text-align: center }
#sales_table td input { text-align: center }
CoffeeScript
$.app = $.app || {}
$.app.MyView = $.app.MyView || {}
$ ->
class MyObject extends Backbone.Model
defaults:
year: 1
sales: 2000
gsf: 1000
# Don't allow GSF < 1 to bypass division by zero errors.
setGSF: (gsf) ->
if gsf >= 1000
@set('gsf',gsf)
return gsf
else
@set('gsf',1000)
return 1000
class MyView extends Backbone.View
el: '#viewContent'
template: _.template($('#my-template').html())
initialize: ->
@modelBinder = new Backbone.ModelBinder()
@render
close: ->
@modelBinder.unbind()
gsfConverter: (direction, value, attribute, model) =>
if direction == 'ViewToModel'
value = model.setGSF(value)
# Since Sales hasn't changed, but Sales/PSF needs to be re-calculated,
# we manually trigger the attribute binding, as per the discussion:
# https://github.com/theironcook/Backbone.ModelBinder/issues/36
@modelBinder._copyModelToView(@modelBinder._attributeBindings['sales'])
return value
else
return value
salesConverter: (direction, value, attribute, model) ->
if direction == 'ViewToModel'
return value
else
return value
salesPSFConverter: (direction, value, attribute, model) ->
if direction == 'ViewToModel'
return value*model.get('gsf')
else
return value/model.get('gsf')
render: ->
$(@el).empty()
$(@el).html @template(@model.toJSON())
bindings =
year: '[name=year]'
gsf: {selector:'[name=gsf]', converter: @gsfConverter},
sales: [{selector:'[name=sales]', converter: @salesConverter},
{selector:'[name=sales_psf]', converter: @salesPSFConverter}]
@modelBinder.bind(@model, $(@el), bindings)
$.extend $.app.MyView, new MyView {model: new MyObject}
$.app.MyView.render()