Using Backbone.js
Vadim Mirgorod aka @dealancer
HELLO!
VADIM MIRGOROD
Team Lead at Blink Reaction
VADIM MIRGOROD
Author of Backbone.js Cookbook
VADIM MIRGOROD
Father
get in touch
@dealancer
dealancer@gmail.com
common js problems
AND WHAT YOU SHOULD AVOID
spaghetti code
events handling * AJAX request * JSON processing
using template * DOM updates
using template * DOM updates
$(document).ready(function() {
$("#getData").click( function() {
$.getJSON("artistsRemote.cfc?method=getArtists&returnformat=json",
function(data) {
$("#artistsContent").empty();
$("#artistsTemplate").tmpl(
'<div class="fname">${fname}</div>' +
'<div class="lname">${lname}</div>'
'<div class="bio">${bio}</div>'
data
).appendTo("#artistsContent");
var nowIs = new Date().toLocaleString();
$('#lastLoad').html( nowIs );
});
});
});
mixing business logic and rendering
is like mixing beer and sparkling wine
copy paste
passing html
in ajax response
re-rendering whole form
on AJAX event
is like if you decided to fix a chair, but did a apartment renovation
MEET
a solution to all of those problems
Backbone.js
- An Open Source MVC
framework - Based on Underscore.js
- Integrates with jQuery
- 100% minimalistic
- Modular and expandable
-
Has a great community
benefits
- Separation of concerns
-
Code re-usability
- Less HTTP traffic
-
Easy to learn
jeremy ashkenas
Created Backbone.js in 2010.
Was known for CofeeScript
and Underscore.js
used by
Groupon Now
FOURSQUARE
air bnb
Linkedin mobile
A SPECIAL FEATURE
Magic that bings fun into the development
and make
clients happy!
LEARN BACKBONE.JS!
modeL
- Contains data
- Implements business logic
Model
var InvoiceItemModel = Backbone.Model.extend({
defaults: { description: '', price: 0, quantity: 1, },
calculateAmount: function() { return this.get('price') * this.get('quantity'); } });
var model = new InvoiceItemModel({
description: 'Toy Tracktor', price: 15, quantity: 1
});
MODEL
-
get, set, has, unset, clear, toJSON, escape
hacker.set('name', "<script>alert('xss')</script>"); var escaped_name = hacker.escape('name');
// <script>alert('xss')</script>
- id, idAttribute, cid
var invoiceItemModel = Backbone.Model.extend({ idAttribute: "_id" });
invoiceItemModel._id = Math.random().toString(36).substr(2);
var id = invoiceItemModel._id;
COLLECTION
- Set of models
- Iteratable
- Sortable
- Filterable
collection
var InvoiceItemCollection = Backbone.Collection.extend({ model: InvoiceItemModel });
var invoiceItemCollection = new InvoiceItemCollection([ {description: 'Wooden Toy House', price: 22, quantity: 3}, {description: 'Farm Animal Set', price: 17, quantity: 1} ]);
COLLECTION
- length, at, indexOf, get
var model = invoiceItemCollection.at(2);
model.get('description'); // Farmer Figure
- add, remove, reset
invoiceItemCollection.reset
([
{description: 'Wooden Toy House', price: 22, quantity: 3},
{description: 'Farm Animal Set', price: 17, quantity: 1}
]);
- chain
var amount = invoiceItemCollection.chain()
.map(function(model) {
return model.get('quantity') * model.get('price');
})
.reduce(function(memo, val) {
return memo + val;
})
.value(); // 83
view
- Renders a model
- Handles model events
- Handles DOM events
- Updates a model
view
var InvoiceItemView = Backbone.View.extend({ tagName: 'tr', template: _.template($('#item-row-template').html()), render: function() { var data = this.model.toJSON(); data.amount = this.model.calculateAmount(); this.$el.html(this.template(data)); return this; },
});
view
var InvoiceItemListView = Backbone.View.extend({ tagName: 'table', template: _.template($('#item-table-template').html()), render: function() { $(this.el).html(this.template()); _.each(this.collection.models, function(model, key) { this.append(model); }, this); return this; },
append: function(model) { var view = new InvoiceItemView({ model: model });
this.$el.append(view.render().el); } });
BINDING MODEL TO A VIEW
var InvoiceItemView = Backbone.View.extend({
// ... initialize: function() { this.listenTo(this.model, 'change', this.render, this); }
});
HANDLING DOM EVENTS
var InvoiceItemView = Backbone.View.extend({
//...
events: {
'click button.delete': 'delete',
},
function: delete() {
this.remove();
}
});
router
- Handles URL changes
- Delegates app flow to a view
router
var Workspace = Backbone.Router.extend({ routes: { '': 'invoiceList', 'invoice': 'invoiceList', 'invoice/:id': 'invoicePage', },
invoiceList: function() { // ...
var view = new InvoiceItemListView({ collection: invoiceItemCollection }
$('body').html(view.render().el);
// ...
}
});
want TO LEARN MORE?
GET BACKBONE.JS COOKBOOK
- Going deeper into models, collections and views
-
Handling DOM events in a view
-
Binding a model and a collection to a view
-
Using templates, forms, grids and layouts
-
Communicating with a RESTful service
-
Working with the local storage
-
Optimizing and testing Backbone application
-
Writing your own Backbone extensions
-
Ensuring compatibility with search engines
- Creating mobile apps with jQueryMobile and PhoneGap
BACKBONE.JS
AND REST
Representational state transfer
-
REST was described by Roy Fielding in 2000:
http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm - Widely used as an API design model
- Client-server
- Uniform interface
- Stateless
- Cacheable
- Layered system
- Typically works over HTTP
REST OVER HTTP
C (CREATE) - POST
R (READ) - GET
U (UPDATE) - PUT
D (DELETE) - DELETE
REST: RESOURCES and QUERIES
FLOW IN Backbone APP
REST IN BACKBONE.JS
var PostModel = Backbone.Model.extend({ // Override id attribute. idAttribute: '_id',
// Define URL root to access model resource. urlRoot: function() { return 'http://example.com/posts/'; }
// Otherwise use url() method to provide full path
// to the model resource. });
var PostCollection = Backbone.Collection.extend({ model: PostModel,
// Define path to the collection resource. url: function() { return 'http://example.com/posts/'; } });
REST IN BACKBONE.JS
// Fetches data into a model. model.fetch();
// Saves a model. model.save();
// Destroys a model. model.destroy();
// Fetches data into a collection. collection.fetch();
// Adds models to a collection. collection.add(models);
// Removes specific models from collection. collection.remove(models);
REST IN BACKBONE.js
// Pass success and error callbacks
model.fetch({
success: function(collection, response, options) {
},
error: function(collection, response, options){
}
});
MONGOLAB.COM
MongoDB in the cloud with a RESTful interface
-
Create new db:
https://mongolab.com/newdb - Get an API key:
https://mongolab.com/user?username=<username> - Perform REST queries:
https://api.mongolab.com/api/1/databases?apiKey=<your-api-key>
https://api.mongolab.com/api/1/databases/sma/collections?apiKey=<your-api-key>
https://api.mongolab.com/api/1/databases/sma/collections/posts?apiKey=<your-api-key>
BACKBONE-MONGODB
An extension, which brings support of
MongoDB Extended JSON format to your app
[{
"_id": {
"$oid": ""
},
title: 'Hey',
body: 'Yo yo yo!'
}]
Usage
_.extend(Backbone.Model.prototype, Backbone.MongoModel.mixin);
Social mobile application
Live demo:
Sources:
http://github.com/dealancer/sma
http://github.com/dealancer/sma
DEMO!
USEFUL
TOOLS AND RESOURCES
Composite application library for Backbone.js
- Specialized view types
- Regions an layouts
- Memory Management
More than just a collections of tools
-
Yo: project scaffolding tool
-
Grunt: JS task management
-
Bower: dependency manager
RESOURCES
-
http://backbonejs.org/ - official docs
-
http://backplug.io/ - bakbone plugins and extensions
-
http://slid.es/dealancer/backbone - slides
QUESTIONS?
THANKS!
Using Backbone.js
By Vadym Myrgorod
Using Backbone.js
- 7,388