Data Binding From The Group Up
by bruth
HTML
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="http://documentcloud.github.com/backbone/backbone-min.js"></script>
<div id="detail-template">
<h1 data-bind="title"></h1>
<em>Published by <span data-bind="author"></span> on <span data-bind="pubDate"></span></em>
<p data-bind="summary"></p>
</div>
<form id="edit-template">
<table>
<tr>
<th>Title</th>
<td><input data-bind="title" name="title"></td>
</tr>
<tr>
<th>Publish Date</th>
<td><input data-bind="pubDate" name="pubDate"></td>
</tr>
<tr>
<th>Summary</th>
<td><textarea data-bind="summary" name="summary"></textarea></td>
</tr>
</table>
</form>
<h1>Console Output</h1>
<ul id="mock-console"></ul>
CSS
#list-item-template, #detail-template, #edit-template {
background-color: #ddd;
padding: 10px;
margin-bottom: 10px;
}
h1, p { margin: 5px 0; }
h1, strong, th { font-weight: bold; }
th { text-align: right; }
td { padding: 5px; }
h1 { font-size: 1.3em; }
em { font-style: italic; font-size: 12px; color: #666 }
input, textarea { width: 300px; padding: 5px; border: 1px solid #999 }
textarea { height: 100px; }
JavaScript
$(function() {
var detailView = $('#detail-template'),
editView = $('#edit-template'),
mockConsole = $('#mock-console');
var data = {
title: 'Secrets of a JavaScript Ninja',
author: 'John Resig',
pubDate: 'Duke Nukem Forever baby..',
summary: 'The untold secrets of the elite JavaScript programmers distilled for intermediate JavaScript programmers, bringing them completely up to speed with the challenges of modern JavaScript development. Explores specific techniques, strategies, and solutions to developing robust, cross-browser, JavaScript code.'
};
var model = new Backbone.Model(data);
function setValue(elem, value) {
elem = $(elem);
if (elem.is('input, textarea')) {
elem.val(value);
} else {
elem.text(value);
}
}
function createChangeHandler(view, attr) {
return function(model, value, options) {
view.find('[data-bind=' + attr + ']').each(function(i, elem) {
setValue(elem, value);
});
}
}
function bindViewToModel(view, model) {
var attr, value, event;
for (attr in model.attributes) {
event = 'change:' + attr;
handler = createChangeHandler(view, attr);
model.bind(event, handler);
// mimic set trigger to populate initial data
model.trigger(event, model, model.get(attr), {});
}
}
bindViewToModel(detailView, model);
bindViewToModel(editView, model);
});