SlideShare a Scribd company logo
Client-side MVC with Backbone.js (reloaded)
Client-side MVC
with Backbone.js
igloo



igloolab.com       michele.berto.li
 @iloveigloo       @MicheleBertoli
Moniga Del Garda
Lago di Garda


                          jQuery
                      HTML5 UPLOADER                       JOBBERONE
                     igloolab.com/jquery-html5-uploader   jobberone.com




  SHARP SQUARE
igloolab.com/sharpsquare
                                                                  KOALA
                              POMODORO WEBAPP                   koooala.com
                              pomodorowebapp.com
Agenda
Why Backbone.js   06:00 min


Architecture      14:00 min


Real World        05:00 min


Tips & Tricks     06:00 min


Extras            04:00 min


Questions         NaN
Why
Backbone.js
Why Backbone.js


From server-side to client-side
Why Backbone.js


From server-side to client-side
We need efficient tools
Why Backbone.js

jQuery is cool but…
Why Backbone.js

jQuery is cool but…
We have to store object informations into
the DOM

 var list = "";
 $.each(data, function (index, value) {
   list += "<li id="item-" + value.Id + "">" + value.Name + "</li>";
 });
 $("ul").append(list);
Why Backbone.js

jQuery is cool but…
We have to store object informations into
the DOM

 var list = "";
 $.each(data, function (index, value) {
   list += "<li id="item-" + value.Id + "">" + value.Name + "</li>";
 });
 $("ul").append(list);
Why Backbone.js
jQuery is cool but…
jQuery callback hell

 $.getJSON("/Items", function (data) {

   var list = "";
   $.each(data, function (index, value) {
     list += "<li id="item-" + value.Id + "">" + value.Name + "</li>";
   });
   $("ul").append(list);

   $("li").click(function () {
     var $this = $(this);
     var id = $this.attr("id").replace("item-", "");
     $.post("/Items", { id: id }, function () {
        $this.fadeOut(function () {
           $this.remove();
        });
     });
   });

 });
Why Backbone.js
jQuery is cool but…
jQuery callback hell

 $.getJSON("/Items", function (data) {

   var list = "";
   $.each(data, function (index, value) {
     list += "<li id="item-" + value.Id + "">" + value.Name + "</li>";
   });
   $("ul").append(list);

   $("li").click(function () {
     var $this = $(this);
     var id = $this.attr("id").replace("item-", "");
     $.post("/Items", { id: id }, function () {
        $this.fadeOut(function () {
           $this.remove();
        });
     });
   });

 });
Why Backbone.js



“It's all too easy to create JavaScript
applications that end up as tangled piles of
jQuery selectors and callbacks.”
Why Backbone.js

So, what do we need?
 •   Abstraction.
 •   Decoupling UI from Data.
 •   No more callbacks.
Why Backbone.js

So, what do we need? (More practically)
• A RESTful service based data layer.

• Events (to keep UI and data up-to-date).

• A template engine.

• A solid routing system.

• All the above things wrapped into a lightweight
 JavaScript framework.
Why Backbone.js



   It exists and it’s called:
         Backbone.js
Architecture
Architecture



               Oct 13th, 2010




   Jeremy
  Ashkenas
Architecture


http://documentcloud.github.com/backbone

https://github.com/documentcloud/backbone

@documentcloud

#documentcloud on IRC

https://groups.google.com/forum/#!forum/backbonejs
Architecture

Backbone.js gives structure to web
applications by providing models with key-
value binding and custom events,
collections with a rich API of enumerable
functions, views with declarative event
handling, and connects it all to your existing
API over a RESTful JSON interface.
Architecture

Backbone.js gives structure to web
applications by providing models with key-
value binding and custom events,
collections with a rich API of enumerable
functions, views with declarative event
handling, and connects it all to your existing
API over a RESTful JSON interface.
Architecture

Backbone.js gives structure to web
applications by providing models with key-
value binding and custom events,
collections with a rich API of enumerable
functions, views with declarative event
handling, and connects it all to your existing
API over a RESTful JSON interface.
Architecture

Backbone.js gives structure to web
applications by providing models with key-
value binding and custom events,
collections with a rich API of enumerable
functions, views with declarative event
handling, and connects it all to your existing
API over a RESTful JSON interface.
Architecture

Backbone.js gives structure to web
applications by providing models with key-
value binding and custom events,
collections with a rich API of enumerable
functions, views with declarative event
handling, and connects it all to your existing
API over a RESTful JSON interface.
Architecture

Backbone.js gives structure to web
applications by providing models with key-
value binding and custom events,
collections with a rich API of enumerable
functions, views with declarative event
handling, and connects it all to your existing
API over a RESTful JSON interface.
Architecture


Dependencies:
• jQuery or Zepto

•   Underscore.js
•   Json2.js
Architecture


MVC
Model / Collection
Template (View)
View (Controller)
Router
Architecture


MVC
Model / Collection
Template (View)
View (Controller)
Router
Architecture


MVC
Model / Collection
Template (View)
View (Controller)
Router
Architecture


MVC
Model / Collection
Template (View)
View (Controller)
Router
Architecture


MVC
Model / Collection
Template (View)
View (Controller)
Router
Model
• Representing data
  (auto-generated).
• Handling persistence.

• Throws events.

• Reusable.
Architecture
Model / Collection - View - Template - Router - Utilities




Model

•   Fetch                                                   HTTP GET      /url
•   Save (new)                                              HTTP POST     /url
•   Save                                                    HTTP PUT      /url/id
•   Destroy                                                 HTTP DELETE   /url/id
Architecture
Model / Collection - View - Template - Router - Utilities




     var Item = Backbone.Model.extend({
       idAttribute: “Id”,
       urlRoot: “/Items”
     });
Architecture
Model / Collection - View - Template - Router - Utilities




    var item = new Item();
    item.set({
       Name: “Igloo”
    }); // trigger change
    item.save(); // trigger sync
Architecture
Model / Collection - View - Template - Router - Utilities



Model
• extend                                                • toJSON       • changedAttributes
•   constructor / initialize                            • fetch        • previous
•   get                                                 • save         • previousAttributes
•   set                                                 • destroy
•   escape                                              • validate
•   has                                                 • isValid
•   unset                                               • url
•   clear                                               • urlRoot
•   id                                                  • parse
•   idAttribute                                         • clone
•   cid                                                 • isNew
• attributes                                            • change
• defaults                                              • hasChanged
Collection
•   A list of models.
•   Underscore methods.
Architecture
Model / Collection - View - Template - Router - Utilities




    var Items = Backbone.Collection.extend({
      model: Item,
      url: "/Items"
    });
Architecture
Model / Collection - View - Template - Router - Utilities




     var items = new Items();
     items.fetch(); // trigger reset
Architecture
Model / Collection - View - Template - Router - Utilities




     items.comparator = function(item) {
        return item.get("Name");
     };
Architecture
Model / Collection - View - Template - Router - Utilities




Collection
• extend                                      • getByCid     • etch

• model                                       • at           • eset

• constructor / initialize                    • length       • create

• models                                      • comparator

• toJSON                                      • sort

• add                                         • pluck

• remove                                      • url

• get                                         • parse
Architecture
Model / Collection - View - Template - Router - Utilities




Collection                                                  • sortBy
                                                            • groupBy
• forEach (each)                                            • sortedIndex
• map                                                       • shuffle
• reduce (foldl, inject)                                    • toArray
• reduceRight (foldr)                                       • size
• find (detect)                                             • first
• filter (select)                                           • initial
• reject                                                    • rest
• every (all)                                               • last
• some (any)                                                • without
• include                                                   • indexOf
• invoke                                                    • lastIndexOf
• max                                                       • isEmpty
• min                                                       • chain
View
•   Manipulates the DOM.
•   Delegates DOM events.
•   Has a Model / Collection.
Architecture
Model / Collection - View - Template - Router - Utilities




                                                            View

  View (Collection)



                                                                   View (Model)
Architecture
Model / Collection - View - Template - Router - Utilities




   var ListView = Backbone.View.extend({
     el: $("ul"),
     initialize: function () {
        this.collection.bind("reset", this.render, this);
     },
     render: function () {
        this.collection.each(this.addItem, this);
        return this;
     },
     addItem: function (item) {
        var itemView = new ItemView({                       var ItemView = Backbone.View.extend({
           model: item                                        tagName: "li",
        });                                                   render: function () {
        this.$el.append(itemView.el);                           this.$el.text(this.model.get("Name"));
        itemView.render();                                      return this;
     }                                                        }
   });                                                      });
Architecture
Model / Collection - View - Template - Router - Utilities




   var ListView = Backbone.View.extend({
     el: $("ul"),
     initialize: function () {
        this.collection.bind("reset", this.render, this);
     },
     render: function () {
        this.collection.each(this.addItem, this);
        return this;
     },
     addItem: function (item) {
        var itemView = new ItemView({                       var ItemView = Backbone.View.extend({
           model: item                                        tagName: "li",
        });                                                   render: function () {
        this.$el.append(itemView.el);                           this.$el.text(this.model.get("Name"));
        itemView.render();                                      return this;
     }                                                        }
   });                                                      });
Architecture
Model / Collection - View - Template - Router - Utilities




   var ListView = Backbone.View.extend({
     el: $("ul"),
     initialize: function () {
        this.collection.bind("reset", this.render, this);
     },
     render: function () {
        this.collection.each(this.addItem, this);
        return this;
     },
     addItem: function (item) {
        var itemView = new ItemView({                       var ItemView = Backbone.View.extend({
           model: item                                        tagName: "li",
        });                                                   render: function () {
        this.$el.append(itemView.el);                           this.$el.text(this.model.get("Name"));
        itemView.render();                                      return this;
     }                                                        }
   });                                                      });
Architecture
Model / Collection - View - Template - Router - Utilities




   var ListView = Backbone.View.extend({
     el: $("ul"),
     initialize: function () {
        this.collection.bind("reset", this.render, this);
     },
     render: function () {
        this.collection.each(this.addItem, this);
        return this;
     },
     addItem: function (item) {
        var itemView = new ItemView({                       var ItemView = Backbone.View.extend({
           model: item                                        tagName: "li",
        });                                                   render: function () {
        this.$el.append(itemView.el);                           this.$el.text(this.model.get("Name"));
        itemView.render();                                      return this;
     }                                                        }
   });                                                      });
Architecture
Model / Collection - View - Template - Router - Utilities




   var ListView = Backbone.View.extend({
     el: $("ul"),
     initialize: function () {
        this.collection.bind("reset", this.render, this);
     },
     render: function () {
        this.collection.each(this.addItem, this);
        return this;
     },
     addItem: function (item) {
        var itemView = new ItemView({                       var ItemView = Backbone.View.extend({
           model: item                                        tagName: "li",
        });                                                   render: function () {
        this.$el.append(itemView.el);                           this.$el.text(this.model.get("Name"));
        itemView.render();                                      return this;
     }                                                        }
   });                                                      });
Architecture
Model / Collection - View - Template - Router - Utilities




   var ListView = Backbone.View.extend({
     el: $("ul"),
     initialize: function () {
        this.collection.bind("reset", this.render, this);
     },
     render: function () {
        this.collection.each(this.addItem, this);
        return this;
     },
     addItem: function (item) {
        var itemView = new ItemView({                       var ItemView = Backbone.View.extend({
           model: item                                        tagName: "li",
        });                                                   render: function () {
        this.$el.append(itemView.el);                           this.$el.text(this.model.get("Name"));
        itemView.render();                                      return this;
     }                                                        }
   });                                                      });
Architecture
Model / Collection - View - Template - Router - Utilities




     var items = new Items();
     var listView = new ListView({
        collection: items
     });
     items.fetch();
Architecture
Model / Collection - View - Template - Router - Utilities




View
  • $ (jQuery or Zepto)                                     • extend

  • render                                                  • constructor / initialize

  • remove                                                  • el

  • make                                                    • $el

  • delegateEvents                                          • setElement

  • undelegateEvents                                        • attributes
Template            (Underscore.js)


Compiles JavaScript templates into functions
that can be evaluated for rendering.

•   Mustache
•   jQuery-tmpl
Architecture
Model / Collection - View - Template - Router - Utilities




     <script type="text/template" id="item-template">
       <li>
          <%= Name %>
       </li>
     </script>
Architecture
Model / Collection - View - Template - Router - Utilities




     var ItemView = Backbone.View.extend({
       …
       template: _.template($("#item-template").html()),
       ...
       render: function () {
           this.$el.html(this.template(this.model.toJSON()));
           return this;
       }
       …
     });
Router
•   Maps urls to function.
•   Enable history / bookmarking.
Architecture
Model / Collection - View - Template - Router - Utilities




     var AppRouter = Backbone.Router.extend({
       routes: {
          "": "init"
       },
       init: function () {
          …
       }
     });
Architecture
Model / Collection - View - Template - Router - Utilities




   window.AppRouter = Backbone.Router.extend({
     routes: {
        "": "loadInvoices",
        "/add": "addInvoice",
        "/show/:id": "showInvoice",
        "/edit/:id": "editInvoice“
     },
     loadInvoices: function () {
        …
     },
     addInvoice: function () {
        …
     },
     showInvoice: function (id) {
        …
     },
     editInvoice: function (id) {
        …
     }
   });
Architecture
Model / Collection - View - Template - Router - Utilities




Router
• extend
• routes
• constructor / initialize
• route
• navigate
Utilities
•   History
•   Sync
•   Utility
Architecture



                      Model /Collection




                                           Data
 Router        View                       Source


                      Template
Real
World
Real World

Polar management
• Smart invoicing web application



Technologies
• .NET RESTful Web Services / MS SQL
• Backbone.js
Real World

             Polar management
Real World
Real World
Real World


Polar management
 window.AppRouter = Backbone.Router.extend({
   routes: {
      …
      "/modifica/:id": "editInvoice“
   },
   editInvoice: function (id) {
      …
   }
 });
Real World


Polar management
 window.AppRouter = Backbone.Router.extend({
   routes: {
      …
      "/modifica/:id": "editInvoice“
   },
   editInvoice: function (id) {
      …
   }
 });
Real World

Koala
• Social media analytics



Technologies
• .NET RESTful Web Services / RavenDB
• Backbone.js
• Highcharts.js
Real World
Real World
Real World

Koala
 window.Logs = Backbone.Collection.extend({
   model: Log,
   url: "/Data",
   comparator: function (log) {
      return log.get("Date");
   },
   sum: function (field) {
      return this.reduce(function (memo, log) {
         return memo + log.get(field);
      }, 0);
   }
 });
Real World

Koala
 window.Logs = Backbone.Collection.extend({
   model: Log,
   url: "/Data",
   comparator: function (log) {
      return log.get("Date");
   },
   sum: function (field) {
      return this.reduce(function (memo, log) {
         return memo + log.get(field);
      }, 0);
   }
 });
Real World

Koala
 window.Logs = Backbone.Collection.extend({
   model: Log,
   url: "/Data",
   comparator: function (log) {
      return log.get("Date");
   },
   sum: function (field) {
      return this.reduce(function (memo, log) {
         return memo + log.get(field);
      }, 0);
   }
 });
Real World

Cammi
• Custom newsletter engine



Technologies
• .NET RESTful Web Services / MS SQL
• Backbone.js
Real World

Cammi
Real World

Cammi
Real World

Cammi
               Load      Load Groups



                             Fetch
             Load User
                             Fetch


                           Load
               Load      Companies
Real World

             Linkedin
Real World

             Linkedin
Real World

             WunderKit
Real World

             Groupon
Real World


             Basecamp
3




Tips &
Tricks
Tips & Tricks

idAttribute

 idAttribute: “id”

 // CouchDB
 idAttribute: “_id”

 // .NET
 idAttribute: “Id”
Tips & Tricks


            Related Models
Tips & Tricks

Related Models

 var Invoice = Backbone.Model.extend({
   idAttribute: “Id”
 });

 var Invoices = Backbone.Collection.extend({
   model: Invoice,
   url: "/Invoices"
 });
Tips & Tricks

                Related Models
Tips & Tricks

                Related Models
Tips & Tricks

Related Models

 var InvoiceDetail = Backbone.Model.extend({
   idAttribute: “Id”
 });

 var InvoiceDetails = Backbone.Collection.extend({
   model: InvoiceDetail,
   url: "/InvoiceDetails“
 });
Tips & Tricks
Related Models

 var Invoice = Backbone.Model.extend({
   idAttribute: "Id",
   initialize: function () {
      this.setInvoiceDetails();
   },
   setInvoiceDetails: function () {
      this.set({
        InvoiceDetails: new InvoiceDetails(this.get("InvoiceDetails"))
      });
   }
 });
Tips & Tricks

                Related Models
Tips & Tricks

                Related Models
Tips & Tricks
Related Models

 var Invoice = Backbone.Model.extend({
   idAttribute: "Id",
   initialize: function () {
      this.setInvoiceDetails();
      this.bind("sync", this.setInvoiceDetails);
   },
   setInvoiceDetails: function () {
      this.set({
        InvoiceDetails: new InvoiceDetails(this.get("InvoiceDetails"))
      });
   }
 });
Extras
Extras

Plugins
• Backbone-Nested
• Backbone.Memento
• Backbone.Validations
• Backbone.localStorage
• backbone.couchdb.js
• …
https://github.com/documentcloud/backbone/wiki/Extensions%2C-
Plugins%2C-Resources
Extras

TDD - Jasmine

 describe("Todo", function() {


   it("Should have a title", function() {
       var todo = new Todo();
       expect(todo.get("title")).toBeDefined();
   });


 });
Extras

Backbone is anti-SEO
http://www.spiffyui.org#!css
http://www.spiffyui.org?_escaped_fragment_=css


http://coding.smashingmagazine.com/2011/09/27/searchable-dynamic-
content-with-ajax-crawling/
Extras


• http://sproutcore.com (Apple/iCloud)

• http://knockoutjs.com

• http://emberjs.com

• http://batmanjs.org (Shopify)
Extras



Cheat Sheet
• http://www.igloolab.com/downloads/backbone-cheatsheet.pdf
Backbone.js
+
• Lightweight
• Powerful
• Code is clean (and maintainable)


-
• Too verbose (for small applications)
3
  Lago di Garda


Questions ?

    Grazie
    www.igloolab.com
      @iloveigloo

More Related Content

Client-side MVC with Backbone.js (reloaded)

  • 3. igloo igloolab.com michele.berto.li @iloveigloo @MicheleBertoli
  • 5. Lago di Garda jQuery HTML5 UPLOADER JOBBERONE igloolab.com/jquery-html5-uploader jobberone.com SHARP SQUARE igloolab.com/sharpsquare KOALA POMODORO WEBAPP koooala.com pomodorowebapp.com
  • 7. Why Backbone.js 06:00 min Architecture 14:00 min Real World 05:00 min Tips & Tricks 06:00 min Extras 04:00 min Questions NaN
  • 10. Why Backbone.js From server-side to client-side We need efficient tools
  • 12. Why Backbone.js jQuery is cool but… We have to store object informations into the DOM var list = ""; $.each(data, function (index, value) { list += "<li id="item-" + value.Id + "">" + value.Name + "</li>"; }); $("ul").append(list);
  • 13. Why Backbone.js jQuery is cool but… We have to store object informations into the DOM var list = ""; $.each(data, function (index, value) { list += "<li id="item-" + value.Id + "">" + value.Name + "</li>"; }); $("ul").append(list);
  • 14. Why Backbone.js jQuery is cool but… jQuery callback hell $.getJSON("/Items", function (data) { var list = ""; $.each(data, function (index, value) { list += "<li id="item-" + value.Id + "">" + value.Name + "</li>"; }); $("ul").append(list); $("li").click(function () { var $this = $(this); var id = $this.attr("id").replace("item-", ""); $.post("/Items", { id: id }, function () { $this.fadeOut(function () { $this.remove(); }); }); }); });
  • 15. Why Backbone.js jQuery is cool but… jQuery callback hell $.getJSON("/Items", function (data) { var list = ""; $.each(data, function (index, value) { list += "<li id="item-" + value.Id + "">" + value.Name + "</li>"; }); $("ul").append(list); $("li").click(function () { var $this = $(this); var id = $this.attr("id").replace("item-", ""); $.post("/Items", { id: id }, function () { $this.fadeOut(function () { $this.remove(); }); }); }); });
  • 16. Why Backbone.js “It's all too easy to create JavaScript applications that end up as tangled piles of jQuery selectors and callbacks.”
  • 17. Why Backbone.js So, what do we need? • Abstraction. • Decoupling UI from Data. • No more callbacks.
  • 18. Why Backbone.js So, what do we need? (More practically) • A RESTful service based data layer. • Events (to keep UI and data up-to-date). • A template engine. • A solid routing system. • All the above things wrapped into a lightweight JavaScript framework.
  • 19. Why Backbone.js It exists and it’s called: Backbone.js
  • 21. Architecture Oct 13th, 2010 Jeremy Ashkenas
  • 23. Architecture Backbone.js gives structure to web applications by providing models with key- value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.
  • 24. Architecture Backbone.js gives structure to web applications by providing models with key- value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.
  • 25. Architecture Backbone.js gives structure to web applications by providing models with key- value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.
  • 26. Architecture Backbone.js gives structure to web applications by providing models with key- value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.
  • 27. Architecture Backbone.js gives structure to web applications by providing models with key- value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.
  • 28. Architecture Backbone.js gives structure to web applications by providing models with key- value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.
  • 29. Architecture Dependencies: • jQuery or Zepto • Underscore.js • Json2.js
  • 30. Architecture MVC Model / Collection Template (View) View (Controller) Router
  • 31. Architecture MVC Model / Collection Template (View) View (Controller) Router
  • 32. Architecture MVC Model / Collection Template (View) View (Controller) Router
  • 33. Architecture MVC Model / Collection Template (View) View (Controller) Router
  • 34. Architecture MVC Model / Collection Template (View) View (Controller) Router
  • 35. Model • Representing data (auto-generated). • Handling persistence. • Throws events. • Reusable.
  • 36. Architecture Model / Collection - View - Template - Router - Utilities Model • Fetch HTTP GET /url • Save (new) HTTP POST /url • Save HTTP PUT /url/id • Destroy HTTP DELETE /url/id
  • 37. Architecture Model / Collection - View - Template - Router - Utilities var Item = Backbone.Model.extend({ idAttribute: “Id”, urlRoot: “/Items” });
  • 38. Architecture Model / Collection - View - Template - Router - Utilities var item = new Item(); item.set({ Name: “Igloo” }); // trigger change item.save(); // trigger sync
  • 39. Architecture Model / Collection - View - Template - Router - Utilities Model • extend • toJSON • changedAttributes • constructor / initialize • fetch • previous • get • save • previousAttributes • set • destroy • escape • validate • has • isValid • unset • url • clear • urlRoot • id • parse • idAttribute • clone • cid • isNew • attributes • change • defaults • hasChanged
  • 40. Collection • A list of models. • Underscore methods.
  • 41. Architecture Model / Collection - View - Template - Router - Utilities var Items = Backbone.Collection.extend({ model: Item, url: "/Items" });
  • 42. Architecture Model / Collection - View - Template - Router - Utilities var items = new Items(); items.fetch(); // trigger reset
  • 43. Architecture Model / Collection - View - Template - Router - Utilities items.comparator = function(item) { return item.get("Name"); };
  • 44. Architecture Model / Collection - View - Template - Router - Utilities Collection • extend • getByCid • etch • model • at • eset • constructor / initialize • length • create • models • comparator • toJSON • sort • add • pluck • remove • url • get • parse
  • 45. Architecture Model / Collection - View - Template - Router - Utilities Collection • sortBy • groupBy • forEach (each) • sortedIndex • map • shuffle • reduce (foldl, inject) • toArray • reduceRight (foldr) • size • find (detect) • first • filter (select) • initial • reject • rest • every (all) • last • some (any) • without • include • indexOf • invoke • lastIndexOf • max • isEmpty • min • chain
  • 46. View • Manipulates the DOM. • Delegates DOM events. • Has a Model / Collection.
  • 47. Architecture Model / Collection - View - Template - Router - Utilities View View (Collection) View (Model)
  • 48. Architecture Model / Collection - View - Template - Router - Utilities var ListView = Backbone.View.extend({ el: $("ul"), initialize: function () { this.collection.bind("reset", this.render, this); }, render: function () { this.collection.each(this.addItem, this); return this; }, addItem: function (item) { var itemView = new ItemView({ var ItemView = Backbone.View.extend({ model: item tagName: "li", }); render: function () { this.$el.append(itemView.el); this.$el.text(this.model.get("Name")); itemView.render(); return this; } } }); });
  • 49. Architecture Model / Collection - View - Template - Router - Utilities var ListView = Backbone.View.extend({ el: $("ul"), initialize: function () { this.collection.bind("reset", this.render, this); }, render: function () { this.collection.each(this.addItem, this); return this; }, addItem: function (item) { var itemView = new ItemView({ var ItemView = Backbone.View.extend({ model: item tagName: "li", }); render: function () { this.$el.append(itemView.el); this.$el.text(this.model.get("Name")); itemView.render(); return this; } } }); });
  • 50. Architecture Model / Collection - View - Template - Router - Utilities var ListView = Backbone.View.extend({ el: $("ul"), initialize: function () { this.collection.bind("reset", this.render, this); }, render: function () { this.collection.each(this.addItem, this); return this; }, addItem: function (item) { var itemView = new ItemView({ var ItemView = Backbone.View.extend({ model: item tagName: "li", }); render: function () { this.$el.append(itemView.el); this.$el.text(this.model.get("Name")); itemView.render(); return this; } } }); });
  • 51. Architecture Model / Collection - View - Template - Router - Utilities var ListView = Backbone.View.extend({ el: $("ul"), initialize: function () { this.collection.bind("reset", this.render, this); }, render: function () { this.collection.each(this.addItem, this); return this; }, addItem: function (item) { var itemView = new ItemView({ var ItemView = Backbone.View.extend({ model: item tagName: "li", }); render: function () { this.$el.append(itemView.el); this.$el.text(this.model.get("Name")); itemView.render(); return this; } } }); });
  • 52. Architecture Model / Collection - View - Template - Router - Utilities var ListView = Backbone.View.extend({ el: $("ul"), initialize: function () { this.collection.bind("reset", this.render, this); }, render: function () { this.collection.each(this.addItem, this); return this; }, addItem: function (item) { var itemView = new ItemView({ var ItemView = Backbone.View.extend({ model: item tagName: "li", }); render: function () { this.$el.append(itemView.el); this.$el.text(this.model.get("Name")); itemView.render(); return this; } } }); });
  • 53. Architecture Model / Collection - View - Template - Router - Utilities var ListView = Backbone.View.extend({ el: $("ul"), initialize: function () { this.collection.bind("reset", this.render, this); }, render: function () { this.collection.each(this.addItem, this); return this; }, addItem: function (item) { var itemView = new ItemView({ var ItemView = Backbone.View.extend({ model: item tagName: "li", }); render: function () { this.$el.append(itemView.el); this.$el.text(this.model.get("Name")); itemView.render(); return this; } } }); });
  • 54. Architecture Model / Collection - View - Template - Router - Utilities var items = new Items(); var listView = new ListView({ collection: items }); items.fetch();
  • 55. Architecture Model / Collection - View - Template - Router - Utilities View • $ (jQuery or Zepto) • extend • render • constructor / initialize • remove • el • make • $el • delegateEvents • setElement • undelegateEvents • attributes
  • 56. Template (Underscore.js) Compiles JavaScript templates into functions that can be evaluated for rendering. • Mustache • jQuery-tmpl
  • 57. Architecture Model / Collection - View - Template - Router - Utilities <script type="text/template" id="item-template"> <li> <%= Name %> </li> </script>
  • 58. Architecture Model / Collection - View - Template - Router - Utilities var ItemView = Backbone.View.extend({ … template: _.template($("#item-template").html()), ... render: function () { this.$el.html(this.template(this.model.toJSON())); return this; } … });
  • 59. Router • Maps urls to function. • Enable history / bookmarking.
  • 60. Architecture Model / Collection - View - Template - Router - Utilities var AppRouter = Backbone.Router.extend({ routes: { "": "init" }, init: function () { … } });
  • 61. Architecture Model / Collection - View - Template - Router - Utilities window.AppRouter = Backbone.Router.extend({ routes: { "": "loadInvoices", "/add": "addInvoice", "/show/:id": "showInvoice", "/edit/:id": "editInvoice“ }, loadInvoices: function () { … }, addInvoice: function () { … }, showInvoice: function (id) { … }, editInvoice: function (id) { … } });
  • 62. Architecture Model / Collection - View - Template - Router - Utilities Router • extend • routes • constructor / initialize • route • navigate
  • 63. Utilities • History • Sync • Utility
  • 64. Architecture Model /Collection Data Router View Source Template
  • 66. Real World Polar management • Smart invoicing web application Technologies • .NET RESTful Web Services / MS SQL • Backbone.js
  • 67. Real World Polar management
  • 70. Real World Polar management window.AppRouter = Backbone.Router.extend({ routes: { … "/modifica/:id": "editInvoice“ }, editInvoice: function (id) { … } });
  • 71. Real World Polar management window.AppRouter = Backbone.Router.extend({ routes: { … "/modifica/:id": "editInvoice“ }, editInvoice: function (id) { … } });
  • 72. Real World Koala • Social media analytics Technologies • .NET RESTful Web Services / RavenDB • Backbone.js • Highcharts.js
  • 75. Real World Koala window.Logs = Backbone.Collection.extend({ model: Log, url: "/Data", comparator: function (log) { return log.get("Date"); }, sum: function (field) { return this.reduce(function (memo, log) { return memo + log.get(field); }, 0); } });
  • 76. Real World Koala window.Logs = Backbone.Collection.extend({ model: Log, url: "/Data", comparator: function (log) { return log.get("Date"); }, sum: function (field) { return this.reduce(function (memo, log) { return memo + log.get(field); }, 0); } });
  • 77. Real World Koala window.Logs = Backbone.Collection.extend({ model: Log, url: "/Data", comparator: function (log) { return log.get("Date"); }, sum: function (field) { return this.reduce(function (memo, log) { return memo + log.get(field); }, 0); } });
  • 78. Real World Cammi • Custom newsletter engine Technologies • .NET RESTful Web Services / MS SQL • Backbone.js
  • 81. Real World Cammi Load Load Groups Fetch Load User Fetch Load Load Companies
  • 82. Real World Linkedin
  • 83. Real World Linkedin
  • 84. Real World WunderKit
  • 85. Real World Groupon
  • 86. Real World Basecamp
  • 88. Tips & Tricks idAttribute idAttribute: “id” // CouchDB idAttribute: “_id” // .NET idAttribute: “Id”
  • 89. Tips & Tricks Related Models
  • 90. Tips & Tricks Related Models var Invoice = Backbone.Model.extend({ idAttribute: “Id” }); var Invoices = Backbone.Collection.extend({ model: Invoice, url: "/Invoices" });
  • 91. Tips & Tricks Related Models
  • 92. Tips & Tricks Related Models
  • 93. Tips & Tricks Related Models var InvoiceDetail = Backbone.Model.extend({ idAttribute: “Id” }); var InvoiceDetails = Backbone.Collection.extend({ model: InvoiceDetail, url: "/InvoiceDetails“ });
  • 94. Tips & Tricks Related Models var Invoice = Backbone.Model.extend({ idAttribute: "Id", initialize: function () { this.setInvoiceDetails(); }, setInvoiceDetails: function () { this.set({ InvoiceDetails: new InvoiceDetails(this.get("InvoiceDetails")) }); } });
  • 95. Tips & Tricks Related Models
  • 96. Tips & Tricks Related Models
  • 97. Tips & Tricks Related Models var Invoice = Backbone.Model.extend({ idAttribute: "Id", initialize: function () { this.setInvoiceDetails(); this.bind("sync", this.setInvoiceDetails); }, setInvoiceDetails: function () { this.set({ InvoiceDetails: new InvoiceDetails(this.get("InvoiceDetails")) }); } });
  • 99. Extras Plugins • Backbone-Nested • Backbone.Memento • Backbone.Validations • Backbone.localStorage • backbone.couchdb.js • … https://github.com/documentcloud/backbone/wiki/Extensions%2C- Plugins%2C-Resources
  • 100. Extras TDD - Jasmine describe("Todo", function() { it("Should have a title", function() { var todo = new Todo(); expect(todo.get("title")).toBeDefined(); }); });
  • 102. Extras • http://sproutcore.com (Apple/iCloud) • http://knockoutjs.com • http://emberjs.com • http://batmanjs.org (Shopify)
  • 104. Backbone.js + • Lightweight • Powerful • Code is clean (and maintainable) - • Too verbose (for small applications)
  • 105. 3 Lago di Garda Questions ? Grazie www.igloolab.com @iloveigloo