Your SlideShare is downloading. ×
0
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	• ...
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)	•  Cli...
What isBackbone.js?
Backbone.js is many things...	•  Javascript Model-View-Controller (MVC)framework	•  Templating engine (through Underscore....
Why Backbone.js?	•  Very flexible 	•  can support multiple ways of structuring things; donot have to use everything; tailor...
The Traditional Web
How web app works?	Client	 Server	 Database	Display	  rendered	  HTML	  1.	  Get	  data	  from	  database	  2.	  Format	  ...
The Traditional Way	Client	 Server	 Database	<ul>	  	  	  <li>David</li>	  	  	  <li>John</li>	  	  	  <li>Jack</li>	  	  ...
E.g. Updating Attributes	Server	 Database	<ul>	  	  	  <li	  id=n1>David</li>	  	  	  <li	  id=n2>John</li>	  	  	  <li	  ...
E.g. Creating Items	Server	 Database	ul	  	  	  li	  id=n1David/li	  	  	  li	  id=n2John/li	  	  	  li	  id=n3Jack/li	  	...
Interactive WebExamples
Web Getting More Interactive	•  The motivation for robust JavascriptApplication Architecture	•  No callback hell	•  Easy t...
MVC withBackbone.js
Javascript UI	Server	 Database	ID	   Name	  1	   David	  2	   John	  3	   Jack	  4	   Dan	  ...	   ...	  ul	  	  	  %	  po...
Collection				CollectionView				Client-Side MVC	Model	ModelView	REST	API	Client	 Server	 Database	ID	   Name	  1	   David	...
Collection				Client-Side MVC	Model	REST	API	Client	 Server	 Database	ID	   Name	  1	   David	  2	   John	  3	   Jack	  4	...
Collection				Server REST API	Model	REST	API	Client	 Server	 Database	ID	   Name	  1	   David	  2	   John	  3	   Jack	  4	...
Web Server API	•  CRUD - Create, Read, Update, Delete 	•  Maps to HTTP methods: POST, GET, PUT,DELETE	•  Scaffolding on mo...
RESTful API	Action	 Method	 URL	Create	 POST	 /posts	Read	 GET	 /posts(/:id)	Update	 PUT	 /posts/:id	Delete	 DELETE	 /post...
Create	var	  PostList	  =	  Backbone.Collection.extend({	  	  	  model:	  PostItem,	  //Reference	  to	  collections	  mod...
Read	//I	  want	  to	  get	  a	  list	  of	  posts	  post_list.fetch();	  	  //Backbone	  will	  automatically	  request	 ...
Update	var	  PostItem	  =	  Backbone.Model.extend({	  	  	  urlRoot:	  /posts	  });	  	  //I	  want	  to	  change	  some	 ...
Delete	//I	  want	  to	  change	  some	  attributes	  of	  an	  item	  (id:	  8)	  item	  =	  post_list.get(8);	  item.des...
Quick Summary	Backbone	 Action	 Method	 URL	collection.create()	 Create	 POST	 /posts	collection.fetch()	model.fetch()	Rea...
Collection				CollectionView				Client-Side MVC	Model	ModelView	REST	API	Client	 Server	 Database	ID	   Name	  1	   David	...
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()	  {	  	  	  	  	...
Create	post_list.create({	  	  	  title:	  New	  Title	  });	  	  	  1:	  request	  /posts	  with	  POST	  method	  attach...
Read	var	  PostListView	  =	  Backbone.View.extend({	  	  	  el:	  ul,	  	  	  initialize:	  function()	  {	  	  	  	  	  ...
Read	post_list.fetch();	  //Backbone	  0.9	  post_list.fetch({reset:true});	  //Backbone	  1.0	  	  1:	  request	  /posts	...
Update	var	  PostItemView	  =	  Backbone.View.extend({	  	  	  tagName:	  	  li,	  	  	  initialize:	  function()	  {	  	 ...
Update	item	  =	  post_list.get(8);	  item.set(title,	  New	  Title);	  item.save();	  	  1:	  request	  /posts/8	  with	 ...
Delete	var	  PostItemView	  =	  Backbone.View.extend({	  	  	  tagName:	  	  li,	  	  	  initialize:	  function()	  {	  	 ...
Delete	item	  =	  post_list.get(8);	  item.destroy();	  	  1:	  request	  /posts/8	  with	  DELETE	  method	  //Automatica...
Collection				CollectionView				Client-Side MVC	Model	ModelView	REST	API	Client	 Server	 Database	ID	   Name	  1	   David	...
Quick Summary	Backbone	 Server Sync	 UI Sync	collection.create()	 POST /posts 	 Triggers add on collection	collection.fetc...
Tips  Tricks	•  {silent:true} to prevent event triggers	•  item.set(title, Silent, {silent: true});	•  {wait: true} if you...
Templating withUnderscore.js
Update	var	  PostItemView	  =	  Backbone.View.extend({	  	  	  tagName:	  	  li,	  	  	  initialize:	  function()	  {	  	 ...
_.template	•  Backbone s hard dependency	•  Write templates like what you expect fromRails, Django, etc. but on the client...
Basic Example	script	  type=text/template	  id=post_item_template	  	  	  	  h1{{=	  post.get(title)	  }}/h1	  	  	  h6{{=...
_ is basically Javascript	script	  type=text/template	  id=post_item_template	  	  	  	  h1{{=	  post.get(title)	  }}/h1	 ...
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)...
Update with _ template	var	  PostItemView	  =	  Backbone.View.extend({	  	  	  tagName:	  	  li,	  	  	  template:	  _.tem...
Tips and Tricks	Conflict	  with	  Rails	  templating.	  Changed	  from	  	  %=	  post.get( title )	  %	  to	  {{=	  post.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. ...
Key Ideas	•  URL should change (so that bookmarks stillwork/links copy still work)	•  Back button should work	•  Loading U...
Backbone Router	var	  AppRouter	  =	  Backbone.Router.extend({	  	  	  routes:	  {	  	  	  	  	  posts/:id:	  getPost,	  	...
HTML5 Push State	•  The old way: location.hash (e.g. #help)	•  Re-write location bar URL	•  Making sure Back Button still ...
DEMO
Quick Recap	•  Javascript MVC framework	•  Backbone Sync automatically syncs with yourbackend	•  And automatically updates...
The Future...
So... Single-Page Apps are theway to go?	•  Very hard to maintain. Gets complex reallyfast.	•  Client code can become heav...
Should you make single-pageapps?	•  Who are your users? (modern browsers?)	•  Are there a lot of interactions? Does thewho...
Many other frameworks...	•  AngularJS (by Google; use traditional JS)	•  Ember.js (very structured; convention overconfigur...
Stack	•  Use well establish frameworks	•  Large community, lots of resources	•  Good conventions (like RESTful, json, etc)...
Feel free to reach out	•  https://github.com/lominming/rails-backbone-example	•  minming@minming.net	•  @lominming	•  Any ...
Upcoming SlideShare
Loading in...5
×

Javascript Application Architecture with Backbone.JS

1,917

Published on

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

Published in: Education, Technology
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,917
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
48
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide
  • 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...
  • Transcript of "Javascript Application Architecture with Backbone.JS"

    1. 1. Javascript ApplicationArchitecture withMin Ming Lo minming@minming.net | @lominming
    2. 2. Agenda •  Intro •  What is Backbone.js? •  The Traditional Web •  MVC with Backbone.js •  Templating with Underscore.js •  Single-Page Apps •  The Future
    3. 3. Intro •  Graduated in 2011 •  B.S. and M.S. Computer Science •  Co-Founder of Pixelapse •  Full-Stack + Front-end + Design
    4. 4. Github for Designers Version Control + Backup + Collaboration http://vimeo.com/pixelapse/pixelapse
    5. 5. 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
    6. 6. What isBackbone.js?
    7. 7. Backbone.js is many things... •  Javascript Model-View-Controller (MVC)framework •  Templating engine (through Underscore.js) •  Single-page apps (through router & history)
    8. 8. 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
    9. 9. The Traditional Web
    10. 10. 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  
    11. 11. 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
    12. 12. 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”)
    13. 13. E.g. Creating Items Server Database ul      li  id=n1David/li      li  id=n2John/li      li  id=n3Jack/li      li  id=n4Dan/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
    14. 14. Interactive WebExamples
    15. 15. 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.
    16. 16. MVC withBackbone.js
    17. 17. 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)
    18. 18. Collection CollectionView Client-Side MVC Model ModelView REST API Client Server Database ID   Name  1   David  2   John  3   Jack  4   Dan  ...   ...  ul  liname/li  .json  var  list  =    1.  Add/Modify/Delete item 2.  Updates server + updatesUI MVC ID   Name  1   David  2   John  3   Jack  4   Dan  ...   ...  
    19. 19. 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
    20. 20. Collection Server REST API Model REST API Client Server Database ID   Name  1   David  2   John  3   Jack  4   Dan  ...   ...  
    21. 21. 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
    22. 22. RESTful API Action Method URL Create POST /posts Read GET /posts(/:id) Update PUT /posts/:id Delete DELETE /posts/:id
    23. 23. 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  
    24. 24. 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  
    25. 25. 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  
    26. 26. 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  
    27. 27. 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
    28. 28. 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  liname/li  var  list  =    1.  Add/Modify/Delete item 2.  Updates server + updatesUI ✓✓??
    29. 29. Backbone Events •  Attributes changes triggers a Backbone Syncevent •  Also triggers change event, re-renders UIaccordingly
    30. 30. 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  
    31. 31. 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  
    32. 32. 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  
    33. 33. 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  
    34. 34. 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  
    35. 35. 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  
    36. 36. 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  
    37. 37. 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  
    38. 38. 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  liname/li  var  list  =    
    39. 39. 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
    40. 40. 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})
    41. 41. Templating withUnderscore.js
    42. 42. 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
    43. 43. _.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
    44. 44. 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  
    45. 45. _ 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  (i6)  {  }}                p{{=  c.body  }}/p            {{  }  }}      {{  });  }}    /script  
    46. 46. Backbone without _ render:  function()  {      $(this.el).html(h1  +  this.model.get(title)  +  /h1);  }  
    47. 47. 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  
    48. 48. 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  
    49. 49. Tips and Tricks Conflict  with  Rails  templating.  Changed  from    %=  post.get( title )  %  to  {{=  post.get( title )  }}          _.templateSettings  =  {      interpolate:  /{{=(.+?)}}/g,      escape:  /{{-­‐(.+?)}}/g,      evaluate:  /{{(.+?)}}/g  };  
    50. 50. Single Page Apps
    51. 51. 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
    52. 52. 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)
    53. 53. 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);  
    54. 54. 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});  
    55. 55. DEMO
    56. 56. 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)
    57. 57. The Future...
    58. 58. 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
    59. 59. 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?
    60. 60. 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/
    61. 61. 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)
    62. 62. Feel free to reach out •  https://github.com/lominming/rails-backbone-example •  minming@minming.net •  @lominming •  Any Javascript, Backbone stuff •  General startup stuff
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×