Client-side MVC with Backbone.js
Upcoming SlideShare
Loading in...5
×
 

Client-side MVC with Backbone.js

on

  • 33,573 views

- Why Backbone

- Why Backbone
- Architecture
- Real World
- Tips & Tricks
- Extras

Statistics

Views

Total Views
33,573
Views on SlideShare
23,455
Embed Views
10,118

Actions

Likes
111
Downloads
817
Comments
2

35 Embeds 10,118

http://makoto-tanaka.com 7501
http://blog.toshimaru.net 1441
http://students.summerisgone.com 537
http://www.codemotion.it 254
http://localhost 71
http://sharee.cc 64
http://roma2012.codemotion.it 48
http://fe.com 42
http://webcache.googleusercontent.com 36
http://web.vabx.com 30
http://jsinghfoss.tumblr.com 16
http://lifeofjs.com 8
http://roma.codemotion.it 7
http://starlinkz.com 6
https://twitter.com 6
http://flavors.me 6
http://192.168.2.3 5
http://test.starlinkz.com 5
https://www.google.co.jp 5
http://www.sharee.cc 4
http://codemotion.loc 4
http://jp.flavors.me 3
http://us-w1.rockmelt.com 3
http://192.168.2.4 3
https://si0.twimg.com 3
http://www.linkedin.com 1
http://mym.corp.yahoo.co.jp 1
http://pt.flavors.me 1
http://digg.com 1
https://twimg0-a.akamaihd.net 1
http://cache.yahoofs.jp 1
https://muliphein.cc.kuleuven.be 1
http://www.twylah.com 1
http://www.tumblr.com 1
http://www.google.co.jp 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Client-side MVC with Backbone.js Client-side MVC with Backbone.js Presentation Transcript

  • Client-side MVCwith Backbone.js
  • iglooigloolab.com michele.berto.li @iloveigloo @MicheleBertoli
  • Lago di Garda
  • Lago di Garda jQuery HTML5 UPLOADER JOBBERONE igloolab.com/jquery-html5-uploader jobberone.com SHARP SQUAREigloolab.com/sharpsquare KOALA POMODORO WEBAPP koooala.com pomodorowebapp.com
  • Agenda
  • Why Backbone.js 06:00 minArchitecture 14:00 minReal World 05:00 minTips & Tricks 06:00 minExtras 04:00 minQuestions 05:00 min
  • WhyBackbone.js
  • Why Backbone.jsFrom server-side to client-side
  • Why Backbone.jsFrom server-side to client-sideWe need efficient tools
  • Why Backbone.jsjQuery is cool but…
  • Why Backbone.jsjQuery is cool but…We have to store object informations intothe DOM var list = ""; $.each(data, function (index, value) { list += "<li id="item-" + value.Id + "">" + value.Name + "</li>"; }); $("ul").append(list);
  • Why Backbone.jsjQuery is cool but…We have to store object informations intothe DOM var list = ""; $.each(data, function (index, value) { list += "<li id="item-" + value.Id + "">" + value.Name + "</li>"; }); $("ul").append(list);
  • Why Backbone.jsjQuery 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.jsjQuery 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“Its all too easy to create JavaScriptapplications that end up as tangled piles ofjQuery selectors and callbacks.”
  • Why Backbone.jsSo, what do we need? • Abstraction. • Decoupling UI from Data. • No more callbacks.
  • Why Backbone.jsSo, 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
  • Architecturehttp://documentcloud.github.com/backbonehttps://github.com/documentcloud/backbone@documentcloud#documentcloud on IRChttps://groups.google.com/forum/#!forum/backbonejs
  • ArchitectureBackbone.js gives structure to webapplications by providing models with key-value binding and custom events,collections with a rich API of enumerablefunctions, views with declarative eventhandling, and connects it all to your existingAPI over a RESTful JSON interface.
  • ArchitectureBackbone.js gives structure to webapplications by providing models with key-value binding and custom events,collections with a rich API of enumerablefunctions, views with declarative eventhandling, and connects it all to your existingAPI over a RESTful JSON interface.
  • ArchitectureBackbone.js gives structure to webapplications by providing models with key-value binding and custom events,collections with a rich API of enumerablefunctions, views with declarative eventhandling, and connects it all to your existingAPI over a RESTful JSON interface.
  • ArchitectureBackbone.js gives structure to webapplications by providing models with key-value binding and custom events,collections with a rich API of enumerablefunctions, views with declarative eventhandling, and connects it all to your existingAPI over a RESTful JSON interface.
  • ArchitectureBackbone.js gives structure to webapplications by providing models with key-value binding and custom events,collections with a rich API of enumerablefunctions, views with declarative eventhandling, and connects it all to your existingAPI over a RESTful JSON interface.
  • ArchitectureBackbone.js gives structure to webapplications by providing models with key-value binding and custom events,collections with a rich API of enumerablefunctions, views with declarative eventhandling, and connects it all to your existingAPI over a RESTful JSON interface.
  • ArchitectureDependencies:• jQuery or Zepto• Underscore.js• Json2.js
  • ArchitectureMVCModel / CollectionTemplate (View)View (Controller)Router
  • ArchitectureMVCModel / CollectionTemplate (View)View (Controller)Router
  • ArchitectureMVCModel / CollectionTemplate (View)View (Controller)Router
  • ArchitectureMVCModel / CollectionTemplate (View)View (Controller)Router
  • ArchitectureMVCModel / CollectionTemplate (View)View (Controller)Router
  • Model• Representing data (auto-generated).• Handling persistence.• Throws events.• Reusable.
  • ArchitectureModel / Collection - View - Template - Router - UtilitiesModel• Fetch HTTP GET /url• Save (new) HTTP POST /url• Save HTTP PUT /url/id• Destroy HTTP DELETE /url/id
  • ArchitectureModel / Collection - View - Template - Router - Utilities var Item = Backbone.Model.extend({ idAttribute: “Id”, urlRoot: “/Items” });
  • ArchitectureModel / Collection - View - Template - Router - Utilities var item = new Item(); item.set({ Name: “Igloo” }); // trigger change item.save(); // trigger sync
  • ArchitectureModel / Collection - View - Template - Router - UtilitiesModel• 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.
  • ArchitectureModel / Collection - View - Template - Router - Utilities var Items = Backbone.Collection.extend({ model: Item, url: "/Items" });
  • ArchitectureModel / Collection - View - Template - Router - Utilities var items = new Items(); items.fetch(); // trigger reset
  • ArchitectureModel / Collection - View - Template - Router - Utilities items.comparator = function(item) { return item.get("Name"); };
  • ArchitectureModel / Collection - View - Template - Router - UtilitiesCollection• extend • getByCid • etch• model • at • eset• constructor / initialize • length • create• models • comparator• toJSON • sort• add • pluck• remove • url• get • parse
  • ArchitectureModel / Collection - View - Template - Router - UtilitiesCollection • 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.
  • ArchitectureModel / Collection - View - Template - Router - Utilities View View (Collection) View (Model)
  • ArchitectureModel / 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; } } }); });
  • ArchitectureModel / 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; } } }); });
  • ArchitectureModel / 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; } } }); });
  • ArchitectureModel / 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; } } }); });
  • ArchitectureModel / 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; } } }); });
  • ArchitectureModel / 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; } } }); });
  • ArchitectureModel / Collection - View - Template - Router - Utilities var items = new Items(); var listView = new ListView({ collection: items }); items.fetch();
  • ArchitectureModel / Collection - View - Template - Router - UtilitiesView • $ (jQuery or Zepto) • extend • render • constructor / initialize • remove • el • make • $el • delegateEvents • setElement • undelegateEvents • attributes
  • Template (Underscore.js)Compiles JavaScript templates into functionsthat can be evaluated for rendering.• Mustache• jQuery-tmpl
  • ArchitectureModel / Collection - View - Template - Router - Utilities <script type="text/template" id="item-template"> <li> <%= Name %> </li> </script>
  • ArchitectureModel / 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.
  • ArchitectureModel / Collection - View - Template - Router - Utilities var AppRouter = Backbone.Router.extend({ routes: { "": "initialize“ }, initialize: function () { … } });
  • ArchitectureModel / 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) { … } });
  • ArchitectureModel / Collection - View - Template - Router - UtilitiesRouter• extend• routes• constructor / initialize• route• navigate
  • Utilities• History• Sync• Utility
  • Architecture Model /Collection Data Router View Source Template
  • RealWorld
  • Real WorldPolar management• Smart invoicing web applicationTechnologies• .NET RESTful Web Services / MS SQL• Backbone.js
  • Real World Polar management
  • Real World
  • Real World
  • Real WorldPolar management window.AppRouter = Backbone.Router.extend({ routes: { … "/modifica/:id": "editInvoice“ }, editInvoice: function (id) { … } });
  • Real WorldPolar management window.AppRouter = Backbone.Router.extend({ routes: { … "/modifica/:id": "editInvoice“ }, editInvoice: function (id) { … } });
  • Real WorldKoala• Social media analyticsTechnologies• NET RESTful Web Services / RavenDB• Backbone.js• Highcharts.js
  • Real World
  • Real World
  • Real WorldKoala 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 WorldKoala 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 WorldKoala 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 Linkedin
  • Real World FourSquare
  • Real World WunderKit
  • Real World Groupon
  • Real World Basecamp
  • 3Tips &Tricks
  • Tips & TricksidAttribute idAttribute: “id” // CouchDB idAttribute: “_id” // .NET idAttribute: “Id”
  • Tips & Tricks Related Models
  • Tips & TricksRelated 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 & TricksRelated Models var InvoiceDetail = Backbone.Model.extend({ idAttribute: “Id” }); var InvoiceDetails = Backbone.Collection.extend({ model: InvoiceDetail, url: "/InvoiceDetails“ });
  • Tips & TricksRelated 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 & TricksRelated 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
  • ExtrasPlugins• Backbone-Nested• Backbone.Memento• Backbone.Validations• Backbone.localStorage• backbone.couchdb.js• …https://github.com/documentcloud/backbone/wiki/Extensions%2C-Plugins%2C-Resources
  • Extras• http://sproutcore.com (Apple/iCloud)• http://knockoutjs.com• http://emberjs.com• http://batmanjs.org (Shopify)
  • ExtrasCheat 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 GardaQuestions ? Grazie www.igloolab.com @iloveigloo