Thinking in Backbone
Backbone implementation of "Thinking in React" example, using ES6.
by infous
HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"></script>
<div id="app"></div>
<script id="search-bar-template" type="text/x-handlebars-template">
<input type="text" placeholder="Search...">
<p>
<input type="checkbox">
Only show products in stock
</p>
</script>
<script id="product-table-template" type="text/x-handlebars-template">
<thead>
<tr>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody></tbody>
</script>
<script id="product-row-template" type="text/x-handlebars-template">
<td>{{#if stocked}}{{name}}{{else}}<span style="color: red">{{name}}</span>{{/if}}</td>
<td>{{ price }}</td>
</script>
<script id="product-category-row-template" type="text/x-handlebars-template">
<th colspan="2">{{ category }}</th>
</script>
<a href="https://github.com/starikovs/thinking-in-backbone/" target="_blank"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png"></a>
CSS
body { padding: 30px; }
Babel + JSX
class Product extends Backbone.Model {
get defaults () {
return {
category: '',
price: '',
stocked: false,
name: ''
};
}
}
class State extends Backbone.Model {
get defaults () {
return {
filterText: '',
inStockOnly: false
};
}
}
class Products extends Backbone.Collection {
get model () {
return Product;
}
}
class ProductRow extends Backbone.View {
initialize () {
this.render();
}
tagName () {
return 'tr';
}
get template () {
return Handlebars.compile($('#product-row-template').html());
}
render () {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
}
class ProductCategoryRow extends Backbone.View {
initialize () {
this.render();
}
tagName () {
return 'tr';
}
get template () {
return Handlebars.compile($('#product-category-row-template').html());
}
render () {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
}
class ProductTable extends Backbone.View {
initialize () {
this.listenTo(this.model, 'change', this.render);
this.render();
}
tagName () {
return 'table';
}
get template () {
return Handlebars.compile($('#product-table-template').html());
}
render () {
this.unregisterSubviews();
this.$el.html(this.template({ }));
let filterText = this.model.get('filterText');
let isStockOnly = this.model.get('isStockOnly');
let rows = this.$('tbody');
let lastCategory = null;
this.collection.each(model => {
if (model.get('name').indexOf(filterText) === -1 ||
(isStockOnly && !model.get('stocked'))) {
return;
}
if (model.get('category') !== lastCategory) {
...