Using Backbone.js

Vadim Mirgorod aka @dealancer



HELLO!

VADIM MIRGOROD

Team Lead at Blink Reaction



http://blinkreaction.com

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

$(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
Photo by UnspaceCollective.



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!

Photo by Kamil Porembiński

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');// &lt;script&gt;alert(&#x27;xss&#x27;)&lt;&#x2F;script&gt;
  • 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 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 callbacksmodel.fetch({  success: function(collection, response, options) {
},
error: function(collection, response, options){
}});

MONGOLAB.COM

MongoDB in the cloud with a RESTful interface

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:



DEMO!






USEFUL

TOOLS AND RESOURCES





Ptoto by James Wheeler.


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








QUESTIONS?



THANKS!

Using Backbone.js

By Vadym Myrgorod

Using Backbone.js

  • 7,127