• Like
  • Save
Javascript Application Architecture with Backbone.JS
Upcoming SlideShare
Loading in...5
×
 

Javascript Application Architecture with Backbone.JS

on

  • 1,827 views

Intro to Javascript Application Architecture with Backbone.JS. Overview on Javascript MVC, templating with Underscore.js, and Single-Page Apps.

Intro to Javascript Application Architecture with Backbone.JS. Overview on Javascript MVC, templating with Underscore.js, and Single-Page Apps.

Statistics

Views

Total Views
1,827
Views on SlideShare
1,819
Embed Views
8

Actions

Likes
4
Downloads
37
Comments
0

1 Embed 8

https://twitter.com 8

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

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
  • Why there’s a need for Backbone for Pixelapse
  • Demo CRUD on traditional.
  • Demo AJAX form on the traditional page.
  • Pixelapse.com - Folder actions. New folder, drag-and-drop, comments section. Gmail.com - starring, etc.
  • Pixelapse.com - Folder actions. New folder, drag-and-drop, comments section. Gmail.com - starring, etc.
  • Demo backbone page
  • Demo json at URL Show the method called at form (after submit)
  • Demo backbone page
  • Demo backbone page
  • Demo backbone page
  • Demo backbone page
  • Demo ID trick
  • Bad example: google search for a location Loading UI: Twitter spinner, facebook, pixelapse animation
  • SEO: No links to crawl and follow. Information is JSON-ed.
  • Real-time like Twitter search, news, chat, feed... No need real-time blogs? articles...

Javascript Application Architecture with Backbone.JS Javascript Application Architecture with Backbone.JS Presentation Transcript

  • Javascript ApplicationArchitecture withMin Ming Lo minming@minming.net | @lominming
  • Agenda •  Intro •  What is Backbone.js? •  The Traditional Web •  MVC with Backbone.js •  Templating with Underscore.js •  Single-Page Apps •  The Future
  • Intro •  Graduated in 2011 •  B.S. and M.S. Computer Science •  Co-Founder of Pixelapse •  Full-Stack + Front-end + Design
  • Github for Designers Version Control + Backup + Collaboration http://vimeo.com/pixelapse/pixelapse
  • Pixelapse Stack •  Web App: Postgres 9.2 + Rails 3.2 (Ruby) +Backbone.js 1.0 •  File Server: Tornado 3.0.1 (Python) •  Client Apps: Python + (Object-C or Qt) •  Heroku + Amazon S3 + PubNub
  • What isBackbone.js?
  • Backbone.js is many things... •  Javascript Model-View-Controller (MVC)framework •  Templating engine (through Underscore.js) •  Single-page apps (through router & history)
  • Why Backbone.js? •  Very flexible •  can support multiple ways of structuring things; donot have to use everything; tailor to your needs •  Huge community •  easy to find resources; get answers; multipleextensions
  • The Traditional Web
  • How web app works? Client Server Database Display  rendered  HTML  1.  Get  data  from  database  2.  Format  into  HTML  tags  3.  Send  back  to  client  Holds  data  
  • The Traditional Way Client Server Database <ul>      <li>David</li>      <li>John</li>      <li>Jack</li>      <li>Dan</li>  </ul>  ID   Name  1   David  2   John  3   Jack  4   Dan  ...   ...  <ul>      <%  posts.each  do  |p|  %>          <li><%=  p.name  %></li>      <%  end  %>  </ul>  • Great for UI only sites. Bad for dynamicinteractive web apps. • E.g. I want to update Dan to Peter MVC
  • E.g. Updating Attributes Server Database <ul>      <li  id=n1>David</li>      <li  id=n2>John</li>      <li  id=n3>Jack</li>      <li  id=n4>Dan</li>  </ul>  ID   Name  1   David  2   John  3   Jack  4   Dan  ...   ...  <ul>      <%  posts.each  do  |p|  %>          <li><%=  p.name  %></li>      <%  end  %>  </ul>  Client 1.  Encode UI with additional information like data-ids 2.  $.ajax(...) call to update ID: 4 with Peter 3.  $(“#n4”).html(“Peter”)
  • E.g. Creating Items Server Database <ul>      <li  id=n1>David</li>      <li  id=n2>John</li>      <li  id=n3>Jack</li>      <li  id=n4>Dan</li>  </ul>  ID   Name  1   David  2   John  3   Jack  4   Dan  ...   ...  <ul>      <%  posts.each  do  |p|  %>          <li><%=  p.name  %></li>      <%  end  %>  </ul>  Client 1.  $.ajax(...) call to create new item 2.  $(“ul”).append("<li id=" + data.id + ">" + data.name+ "</li>") Duplication of logic
  • Interactive WebExamples
  • Web Getting More Interactive •  The motivation for robust JavascriptApplication Architecture •  No callback hell •  Easy to update UI, easy to update server •  Examples •  Gmail, Facebook, Twitter, Pixelapse, etc.
  • MVC withBackbone.js
  • Javascript UI Server Database ID   Name  1   David  2   John  3   Jack  4   Dan  ...   ...  <ul>      <%  posts.each  do  |p|  %>          <li><%=  p.name  %></li>      <%  end  %>  </ul>  Client 1.  Move rendering logic to client-side 2.  Sometimes called Javascript UI because Javascript isdoing the templating now (not the server)
  • Collection CollectionView Client-Side MVC Model ModelView REST API Client Server Database ID   Name  1   David  2   John  3   Jack  4   Dan  ...   ...  <ul>  <li>name</li>  .json  var  list  =    1.  Add/Modify/Delete item 2.  Updates server + updatesUI MVC ID   Name  1   David  2   John  3   Jack  4   Dan  ...   ...  
  • Collection Client-Side MVC Model REST API Client Server Database ID   Name  1   David  2   John  3   Jack  4   Dan  ...   ...  Let’s us see how Backbone help us update the serverwhen we modify the list
  • Collection Server REST API Model REST API Client Server Database ID   Name  1   David  2   John  3   Jack  4   Dan  ...   ...  
  • Web Server API •  CRUD - Create, Read, Update, Delete •  Maps to HTTP methods: POST, GET, PUT,DELETE •  Scaffolding on most modern webframeworks like Rails or Django
  • RESTful API Action Method URL Create POST /posts Read GET /posts(/:id) Update PUT /posts/:id Delete DELETE /posts/:id
  • Create var  PostList  =  Backbone.Collection.extend({      model:  PostItem,  //Reference  to  collections  model      url:  /posts  });    post_list  =  new  PostList();    //I  want  to  create  a  new  item  in  the  collection  post_list.create({      title:  New  Title  });      //Backbone  will  automatically  request  /posts  with  POST  method  attaching  the  data  
  • Read //I  want  to  get  a  list  of  posts  post_list.fetch();    //Backbone  will  automatically  request  /posts  with  GET  method          //I  want  to  get  one  post  item  =  post_list.get(1);  item.fetch();    //Backbone  will  automatically  request  /posts/1  with  GET  method  
  • Update var  PostItem  =  Backbone.Model.extend({      urlRoot:  /posts  });    //I  want  to  change  some  attributes  of  an  item  (id:  8)  item  =  post_list.get(8);  item.set(title,  New  Title);  item.save();    //Backbone  will  automatically  request  /posts/8  with  PUT  method  attaching  the  data  
  • Delete //I  want  to  change  some  attributes  of  an  item  (id:  8)  item  =  post_list.get(8);  item.destroy();    //Backbone  will  automatically  request  /posts/8  with  DELETE  method  
  • Quick Summary Backbone Action Method URL collection.create() Create POST /posts collection.fetch() model.fetch() Read GET /posts(/:id) model.set(...) model.save() Update PUT /posts/:id model.destroy() Delete DELETE /posts/:id
  • Collection CollectionView Client-Side MVC Model ModelView REST API Client Server Database ID   Name  1   David  2   John  3   Jack  4   Dan  ...   ...  ID   Name  1   David  2   John  3   Jack  4   Dan  ...   ...   .json  <ul>  <li>name</li>  var  list  =    1.  Add/Modify/Delete item 2.  Updates server + updatesUI ✓"✓"?"?"
  • Backbone Events •  Attributes changes triggers a Backbone Syncevent •  Also triggers change event, re-renders UIaccordingly
  • Create var  PostListView  =  Backbone.View.extend({      el:  "ul",      initialize:  function()  {          this.collection.bind(add,  this.addPostItem);          this.collection.bind(reset,  this.render,  this);    },      render:  function()  {          $(this.el).html("");          this.collection.each(this.addPostItem);          return  this;  },      addPostItem:  function(item)  {          var  post_item_view  =  new  PostItemView({model:  item});          $(this.el).append(post_item_view.render().el);  }  });      //Every  time  an  item  is  ADD-­‐ed  to  the  collection,  addPostItem()  would  be  called  
  • Create post_list.create({      title:  New  Title  });      1:  request  /posts  with  POST  method  attaching  the  data  //Automatically  tell  the  server  new  item  is  created    2:  addPostItem()  will  automatically  be  called  //Automatically  update  the  UI  to  include  new  item  
  • Read var  PostListView  =  Backbone.View.extend({      el:  "ul",      initialize:  function()  {          this.collection.bind(add,  this.addPostItem);          this.collection.bind(reset,  this.render,  this);    },      render:  function()  {          $(this.el).html("");          this.collection.each(this.addPostItem);          return  this;  },      addPostItem:  function(item)  {          var  post_item_view  =  new  PostItemView({model:  item});          $(this.el).append(post_item_view.render().el);  }  });      //Every  time  a  collection  is  RESET-­‐ed,  render()  would  be  called  
  • Read post_list.fetch();  //Backbone  0.9  post_list.fetch({reset:true});  //Backbone  1.0    1:  request  /posts  with  GET  method  //Get  list  of  posts  from  server    2:  render()  will  automatically  be  called        loop  through  each  item  (from  the  list  of  posts)        for  each  item,  append  to  the  el  (<ul>)  //Automatically  update  the  UI  with  list  of  items  
  • Update var  PostItemView  =  Backbone.View.extend({      tagName:    "li",      initialize:  function()  {          this.model.on(change,  this.render,  this);          this.model.on(destroy,  this.remove,  this);      },      render:  function()  {          $(this.el).html(<h1>  +  this.model.get(name)  +  </h1>);          return  this;      },  });    //Every  time  an  item  has  CHANGE-­‐ed,  render()  would  be  called  
  • Update item  =  post_list.get(8);  item.set(title,  New  Title);  item.save();    1:  request  /posts/8  with  PUT  method  attaching  the  data  //Automatically  tell  server  that  item  has  changed    2:  render()  will  automatically  be  called  //Automatically  update  the  UI  to  include  the  changes  
  • Delete var  PostItemView  =  Backbone.View.extend({      tagName:    "li",      initialize:  function()  {          this.model.on(change,  this.render,  this);          this.model.on(destroy,  this.remove,  this);      },      remove:  function()  {          $(this.el).fadeOut(300,  function()  {  $(this).remove();  });      },  });    //Every  time  an  item  is  DESTROY-­‐ed,  remove()  would  be  called  
  • Delete item  =  post_list.get(8);  item.destroy();    1:  request  /posts/8  with  DELETE  method  //Automatically  tell  server  that  item  has  been  deleted    2:  remove()  will  automatically  be  called  //Automatically  update  the  UI  to  remove  the  item  
  • Collection CollectionView Client-Side MVC Model ModelView REST API Client Server Database ID   Name  1   David  2   John  3   Jack  4   Dan  ...   ...  1.  Add/Modify/Delete item 2.  Updates server + updatesUI ✓"✓"✓"✓"ID   Name  1   David  2   John  3   Jack  4   Dan  ...   ...   .json  <ul>  <li>name</li>  var  list  =    
  • Quick Summary Backbone Server Sync UI Sync collection.create() POST /posts Triggers add on collection collection.fetch() model.fetch() GET /posts(/:id) Triggers reset on collection model.set(...) model.save() PUT /posts/:id Triggers change on model model.destroy() DELETE /posts/:id Triggers destroy on model
  • Tips & Tricks •  {silent:true} to prevent event triggers •  item.set("title", "Silent", {silent: true}); •  {wait: true} if youd like to wait for the serverrespond before updating the UI •  post_list.create({ title: "Waiting..." }, {wait: true})
  • Templating withUnderscore.js
  • Update var  PostItemView  =  Backbone.View.extend({      tagName:    "li",      initialize:  function()  {          this.model.on(change,  this.render,  this);          this.model.on(destroy,  this.remove,  this);      },      render:  function()  {          $(this.el).html(<h1>  +  this.model.get(name)  +  </h1>);          return  this;      },  });  • Ugly and clumsy to write inline html like this
  • _.template •  Backbone s hard dependency •  Write templates like what you expect fromRails, Django, etc. but on the client-side •  Interpreted and rendered by the browser
  • Basic Example <script  type="text/template"  id="post_item_template">        <h1>{{=  post.get("title")  }}</h1>      <h6>{{=  post.get("name")  }}</h6>      <p>{{=  post.get("content")  }}</p>    </script>  
  • _ is basically Javascript <script  type="text/template"  id="post_item_template">        <h1>{{=  post.get("title")  }}</h1>      <h6>{{=  post.get("name")  }}</h6>      <p>{{=  post.get("content")  }}</p>        {{  _.each(post.get("comments"),  function(c,  i)  {  }}          {{  if  (i<6)  {  }}                <p>{{=  c.body  }}</p>            {{  }  }}      {{  });  }}    </script>  
  • Backbone without _ render:  function()  {      $(this.el).html(<h1>  +  this.model.get(title)  +  </h1>);  }  
  • Backbone with _ template:  _.template($(#post_item_template).html()),      render:  function()  {      $(this.el).html(this.template(  {  post:  this.model  }  ));  }        <script  type="text/template"  id="post_item_template">      <h1>{{=  post.get("title")  }}</h1>  </script>  
  • Update with _ template var  PostItemView  =  Backbone.View.extend({      tagName:    "li",      template:  _.template($(#post_item_template).html()),      initialize:  function()  {          this.model.on(change,  this.render,  this);          this.model.on(destroy,  this.remove,  this);      },      render:  function()  {          $(this.el).html(this.template(  {  post:  this.model  }  ));          return  this;      },  });    //Every  time  an  item  has  CHANGE-­‐ed,  render()  would  be  called,  and  the  template  will  be  used  
  • Tips and Tricks Conflict  with  Rails  templating.  Changed  from    <%=  post.get( title )  %>  to  {{=  post.get( title )  }}          _.templateSettings  =  {      interpolate:  /{{=(.+?)}}/g,      escape:  /{{-­‐(.+?)}}/g,      evaluate:  /{{(.+?)}}/g  };  
  • Single Page Apps
  • What is Single Page App? •  Single Page Apps a.k.a. Complete JavascriptUI a.k.a. Single-Page Javascript UI •  No refresh. Everything is AJAX-ed. •  Feels more like an app, less like a website(less request/respond feel) •  E.g. Twitter, Gmail, iCloud, Google Docs
  • Key Ideas •  URL should change (so that bookmarks stillwork/links copy still work) •  Back button should work •  Loading UI •  Javascript handles the routes (the URLs)
  • Backbone Router var  AppRouter  =  Backbone.Router.extend({      routes:  {          "posts/:id":  "getPost",          "contact":  "getContact",          "*actions":  "defaultRoute"      },      getPost:  function(id)  {          //execute  stuff  here      },      ...  }    var  app_router  =  new  AppRouter;  app_router.navigate("posts/123",  true);  
  • HTML5 Push State •  The old way: location.hash (e.g. #help) •  Re-write location bar URL •  Making sure Back Button still works •  IE 10 onwards •  http://caniuse.com/#search=history Backbone.history.start({pushState:  true});  
  • DEMO
  • Quick Recap •  Javascript MVC framework •  Backbone Sync automatically syncs with yourbackend •  And automatically updates your UI •  Templating engine (through Underscore.js) •  Single-page apps (through router & history)
  • The Future...
  • So... Single-Page Apps are theway to go? •  Very hard to maintain. Gets complex reallyfast. •  Client code can become heavy (easily see2-3x increase in JS file size) •  SEO will be challenging •  Have to think about User Experience •  Not for older browsers
  • Should you make single-pageapps? •  Who are your users? (modern browsers?) •  Are there a lot of interactions? Does thewhole site needs to be a single app? •  Does your web app need to be in real-time?
  • Many other frameworks... •  AngularJS (by Google; use traditional JS) •  Ember.js (very structured; convention overconfiguration) •  KnockoutJS (two way bindings) •  Resources: •  http://coding.smashingmagazine.com/2012/07/27/journey-through-the-javascript-mvc-jungle/
  • Stack •  Use well establish frameworks •  Large community, lots of resources •  Good conventions (like RESTful, json, etc) •  Easy to find plug-ins, extensions (less re-write) •  Recommendations •  Web frameworks: Rails, Django, (Node.js) •  Javascript MVC: Backbone (Angular, Ember,Knockout)
  • Feel free to reach out •  https://github.com/lominming/rails-backbone-example •  minming@minming.net •  @lominming •  Any Javascript, Backbone stuff •  General startup stuff