Philip Poots
     @pootsbook

     Ruby Developer

     Audacio.us


3

18

3
va Sc ri pt
Ja
Structure
State
Speed
Structure Framework
State Application
Speed Javascript
Structure Framework
State Application
Speed Javascript
$.getJSON("http://example.com/?
feed=json&jsonp=?", function(data){
    $('#content').html("<a href=""
+ data[0].permalink + "">" +
data[0].title + "</a>");
    $('#Date').html(data[0].date);
    $
('#Excerpt').html(data[0].excerpt);
    $('#Excerpt').after("<a href=
"" + data[0].permalink + ""
class="more">read on &raquo;</
a>");
  });
STRUCTURE   MVC Model View Controller
            Pattern
            —1979
            Architecture
            —Separate domain logic & UI
            Server-Side MVC
            —Ruby on Rails
STRUCTURE   MVC on Server
STRUCTURE   MVC on Client
STRUCTURE   Backbone Model
 window.Todo = Backbone.Model.extend({
      defaults: {
         done: false
      },
 
      toggle: function() {
         this.save(
   
 
 
 {done: !this.get("done")}
         );
      }
    });
STRUCTURE   Backbone Model
 window.Todo = Backbone.Model.extend({
      defaults: {
         done: false
      },
 
      toggle: function() {
         this.save(
   
 
 
 {done: !this.get("done")}
         );
      }
    });
STRUCTURE   Backbone Model
 window.Todo = Backbone.Model.extend({
      defaults: {
         done: false
      },
 
      toggle: function() {
         this.save(
   
 
 
 {done: !this.get("done")}
         );
      }
    });
STRUCTURE   Backbone Collection
 window.TodoList =
 Backbone.Collection.extend({
    model: Todo,
    localStorage: new Store("todos"),
    done: function() {
      return this.filter(function(todo) 
      { return todo.get('done'); });
    },
    remaining: function() {
      return this.without.apply(
        this, this.done());
     }
   });
STRUCTURE   Backbone Collection
 window.TodoList =
 Backbone.Collection.extend({
    model: Todo,
    localStorage: new Store("todos"),
    done: function() {
      return this.filter(function(todo) 
      { return todo.get('done'); });
    },
    remaining: function() {
      return this.without.apply(
        this, this.done());
     }
   });
STRUCTURE   Backbone Collection
 window.TodoList =
 Backbone.Collection.extend({
    model: Todo,
    localStorage: new Store("todos"),
    done: function() {
      return this.filter(function(todo) 
      { return todo.get('done'); });
    },
    remaining: function() {
      return this.without.apply(
        this, this.done());
     }
   });
STRUCTURE   Backbone Collection
 window.TodoList =
 Backbone.Collection.extend({
    model: Todo,
    localStorage: new Store("todos"),
    done: function() {
      return this.filter(function(todo) 
      { return todo.get('done'); });
    },
    remaining: function() {
      return this.without.apply(
        this, this.done());
     }
   });
STRUCTURE   Backbone Collection
 window.TodoList =
 Backbone.Collection.extend({
    model: Todo,
    localStorage: new Store("todos"),
    done: function() {
      return this.filter(function(todo) 
      { return todo.get('done'); });
    },
    remaining: function() {
      return this.without.apply(
        this, this.done());
     }
   });
STRUCTURE   Backbone Collection
 window.TodoList =
 Backbone.Collection.extend({
    model: Todo,
    localStorage: new Store("todos"),
    done: function() {
      return this.filter(function(todo) 
      { return todo.get('done'); });
    },
    remaining: function() {
      return this.without.apply(
        this, this.done());
     }
   });
STRUCTURE   Backbone View
 window.TodoView = Backbone.View.extend({
     tagName: "li",
     template: $("#item-template").template(),
     events: {
       "change   .check"        : "toggleDone",
       "dblclick .todo-content" : "edit",
       "click    .todo-destroy" : "destroy",
       "keypress .todo-input"   :
 "updateOnEnter",
       "blur     .todo-input"   : "close"
     },
STRUCTURE   Backbone View
 window.TodoView = Backbone.View.extend({
     tagName: "li",
     template: $("#item-template").template(),
     events: {
       "change   .check"        : "toggleDone",
       "dblclick .todo-content" : "edit",
       "click    .todo-destroy" : "destroy",
       "keypress .todo-input"   :
 "updateOnEnter",
       "blur     .todo-input"   : "close"
     },
STRUCTURE   Backbone View
 window.TodoView = Backbone.View.extend({
     tagName: "li",
     template: $("#item-template").template(),
     events: {
       "change   .check"        : "toggleDone",
       "dblclick .todo-content" : "edit",
       "click    .todo-destroy" : "destroy",
       "keypress .todo-input"   :
 "updateOnEnter",
       "blur     .todo-input"   : "close"
     },
STRUCTURE   JS Template
 window.TodoView = Backbone.View.extend({
     tagName: "li",
     template: $("#item-template").template(),
     events: {
       "change   .check"        : "toggleDone",
       "dblclick .todo-content" : "edit",
       "click    .todo-destroy" : "destroy",
       "keypress .todo-input"   :
 "updateOnEnter",
       "blur     .todo-input"   : "close"
     },
STRUCTURE   Backbone View
 window.TodoView = Backbone.View.extend({
     tagName: "li",
     template: $("#item-template").template(),
     events: {
       "change   .check"        : "toggleDone",
       "dblclick .todo-content" : "edit",
       "click    .todo-destroy" : "destroy",
       "keypress .todo-input"   :
 "updateOnEnter",
       "blur     .todo-input"   : "close"
     },
STRUCTURE   Backbone View
 initialize: function() {
   _.bindAll(this, 'render', 'close', 'remove',
 'edit');
   this.model.bind('change', this.render);
   this.model.bind('destroy', this.remove);
 },
 render: function() {
   var element = jQuery.tmpl(this.template,
 this.model.toJSON());
   $(this.el).html(element);
   this.input = this.$(".todo-input");
   return this;
 },
STRUCTURE   Backbone View
 initialize: function() {
   _.bindAll(this, 'render', 'close', 'remove',
 'edit');
   this.model.bind('change', this.render);
   this.model.bind('destroy', this.remove);
 },
 render: function() {
   var element = jQuery.tmpl(this.template,
 this.model.toJSON());
   $(this.el).html(element);
   this.input = this.$(".todo-input");
   return this;
 },
STRUCTURE   Backbone View

 toggleDone: function() {
       this.model.toggle();
     },
STRUCTURE   Backbone Router
 var Workspace =
 Backbone.Router.extend({
 
   routes: {
      "help": "help" // #help
   },
 
   help: function() {
      ...
   }
 });
STRUCTURE   Backbone Router
 var Workspace =
 Backbone.Router.extend({
 
   routes: {
      "help": "help" // #help
   },
 
   help: function() {
      ...
   }
 });
STRUCTURE   Backbone Router
 var Workspace =
 Backbone.Router.extend({
 
   routes: {
      "help": "help" // #help
   },
 
   help: function() {
      ...
   }
 });
STRUCTURE   Clean Code
Structure Framework
State Application
Speed Javascript
S TAT E   HTTP/1.1
          “It is a…stateless protocol”
           —RFC 2616 (June 1999)
S TAT E   HTTP/1.1
          “It is a…stateless protocol”
           —RFC 2616 (June 1999)

          cookies

          sessions

          form variables

          URI parameters
S TAT E   Server Owns State




          Client     Server
S TAT E   Request GET   / HTTP/1.1




          Client         Server
S TAT E   Response HTTP/1.1   200 OK




          Client       Server
S TAT E   AJAX asynchronicity




          Client     Server
S TAT E   Infrastructure
                 Client



                 Server
S TAT E   Infrastructure
                 Client



               Web Server
S TAT E   Infrastructure
                  Client



                Web Server

            RESTful Application
S TAT E   Infrastructure
                  Client



                Web Server

            RESTful Application

                 Database
S TAT E   Infrastructure
                   Client

            JavaScript MVC App.


                Web Server

             RESTful API / App.

                 Database
S TAT E   Infrastructure
                  Client

            JavaScript MVC App.

               Local Storage




          Bo nu s!
Structure Framework
State Application
Speed Javascript
SPEED   JavaScript is Fast
        Google v8 JS engine
        —focus on optimizing speed
        It runs in the browser
        —cuts out server requests
        —spares server resources
        —instantaneous UI
SPEED   Data Transport
        JSON data only
        —no markup
SPEED   Data Transport
          JSON data only
          —no markup
{ "id": 1, 
  "first_name": "Philip", 
  "last_name": "Poots", 
  "twitter": "@pootsbook"}
   vs.
"<div id="user_1">n<dl>n<dt>Name</dt>
n<dd>Philip Poots</dd>n<dt>Twitter
handle:</dt>n<dd>@pootsbook</dd>n</dl>
n</div>"
Structure Framework
State Application
Speed Javascript
http://documentcloud.github.com/backbone/
JavaScript Web Apps




@maccman

Backbone.js — Introduction to client-side JavaScript MVC

  • 2.
    Philip Poots @pootsbook Ruby Developer Audacio.us 3 18 3
  • 12.
    va Sc ript Ja
  • 13.
  • 14.
  • 15.
  • 16.
    $.getJSON("http://example.com/? feed=json&jsonp=?", function(data){ $('#content').html("<a href="" + data[0].permalink + "">" + data[0].title + "</a>"); $('#Date').html(data[0].date); $ ('#Excerpt').html(data[0].excerpt); $('#Excerpt').after("<a href= "" + data[0].permalink + "" class="more">read on &raquo;</ a>"); });
  • 17.
    STRUCTURE MVC Model View Controller Pattern —1979 Architecture —Separate domain logic & UI Server-Side MVC —Ruby on Rails
  • 18.
    STRUCTURE MVC on Server
  • 19.
    STRUCTURE MVC on Client
  • 20.
    STRUCTURE Backbone Model window.Todo = Backbone.Model.extend({ defaults: { done: false }, toggle: function() { this.save( {done: !this.get("done")} ); } });
  • 21.
    STRUCTURE Backbone Model window.Todo = Backbone.Model.extend({ defaults: { done: false }, toggle: function() { this.save( {done: !this.get("done")} ); } });
  • 22.
    STRUCTURE Backbone Model window.Todo = Backbone.Model.extend({ defaults: { done: false }, toggle: function() { this.save( {done: !this.get("done")} ); } });
  • 23.
    STRUCTURE Backbone Collection window.TodoList = Backbone.Collection.extend({ model: Todo, localStorage: new Store("todos"), done: function() { return this.filter(function(todo) { return todo.get('done'); }); }, remaining: function() { return this.without.apply( this, this.done()); } });
  • 24.
    STRUCTURE Backbone Collection window.TodoList = Backbone.Collection.extend({ model: Todo, localStorage: new Store("todos"), done: function() { return this.filter(function(todo) { return todo.get('done'); }); }, remaining: function() { return this.without.apply( this, this.done()); } });
  • 25.
    STRUCTURE Backbone Collection window.TodoList = Backbone.Collection.extend({ model: Todo, localStorage: new Store("todos"), done: function() { return this.filter(function(todo) { return todo.get('done'); }); }, remaining: function() { return this.without.apply( this, this.done()); } });
  • 26.
    STRUCTURE Backbone Collection window.TodoList = Backbone.Collection.extend({ model: Todo, localStorage: new Store("todos"), done: function() { return this.filter(function(todo) { return todo.get('done'); }); }, remaining: function() { return this.without.apply( this, this.done()); } });
  • 27.
    STRUCTURE Backbone Collection window.TodoList = Backbone.Collection.extend({ model: Todo, localStorage: new Store("todos"), done: function() { return this.filter(function(todo) { return todo.get('done'); }); }, remaining: function() { return this.without.apply( this, this.done()); } });
  • 28.
    STRUCTURE Backbone Collection window.TodoList = Backbone.Collection.extend({ model: Todo, localStorage: new Store("todos"), done: function() { return this.filter(function(todo) { return todo.get('done'); }); }, remaining: function() { return this.without.apply( this, this.done()); } });
  • 29.
    STRUCTURE Backbone View window.TodoView = Backbone.View.extend({ tagName: "li", template: $("#item-template").template(), events: { "change .check" : "toggleDone", "dblclick .todo-content" : "edit", "click .todo-destroy" : "destroy", "keypress .todo-input" : "updateOnEnter", "blur .todo-input" : "close" },
  • 30.
    STRUCTURE Backbone View window.TodoView = Backbone.View.extend({ tagName: "li", template: $("#item-template").template(), events: { "change .check" : "toggleDone", "dblclick .todo-content" : "edit", "click .todo-destroy" : "destroy", "keypress .todo-input" : "updateOnEnter", "blur .todo-input" : "close" },
  • 31.
    STRUCTURE Backbone View window.TodoView = Backbone.View.extend({ tagName: "li", template: $("#item-template").template(), events: { "change .check" : "toggleDone", "dblclick .todo-content" : "edit", "click .todo-destroy" : "destroy", "keypress .todo-input" : "updateOnEnter", "blur .todo-input" : "close" },
  • 32.
    STRUCTURE JS Template window.TodoView = Backbone.View.extend({ tagName: "li", template: $("#item-template").template(), events: { "change .check" : "toggleDone", "dblclick .todo-content" : "edit", "click .todo-destroy" : "destroy", "keypress .todo-input" : "updateOnEnter", "blur .todo-input" : "close" },
  • 33.
    STRUCTURE Backbone View window.TodoView = Backbone.View.extend({ tagName: "li", template: $("#item-template").template(), events: { "change .check" : "toggleDone", "dblclick .todo-content" : "edit", "click .todo-destroy" : "destroy", "keypress .todo-input" : "updateOnEnter", "blur .todo-input" : "close" },
  • 34.
    STRUCTURE Backbone View initialize: function() { _.bindAll(this, 'render', 'close', 'remove', 'edit'); this.model.bind('change', this.render); this.model.bind('destroy', this.remove); }, render: function() { var element = jQuery.tmpl(this.template, this.model.toJSON()); $(this.el).html(element); this.input = this.$(".todo-input"); return this; },
  • 35.
    STRUCTURE Backbone View initialize: function() { _.bindAll(this, 'render', 'close', 'remove', 'edit'); this.model.bind('change', this.render); this.model.bind('destroy', this.remove); }, render: function() { var element = jQuery.tmpl(this.template, this.model.toJSON()); $(this.el).html(element); this.input = this.$(".todo-input"); return this; },
  • 36.
    STRUCTURE Backbone View toggleDone: function() { this.model.toggle(); },
  • 37.
    STRUCTURE Backbone Router var Workspace = Backbone.Router.extend({ routes: { "help": "help" // #help }, help: function() { ... } });
  • 38.
    STRUCTURE Backbone Router var Workspace = Backbone.Router.extend({ routes: { "help": "help" // #help }, help: function() { ... } });
  • 39.
    STRUCTURE Backbone Router var Workspace = Backbone.Router.extend({ routes: { "help": "help" // #help }, help: function() { ... } });
  • 40.
    STRUCTURE Clean Code
  • 41.
  • 42.
    S TAT E HTTP/1.1 “It is a…stateless protocol” —RFC 2616 (June 1999)
  • 43.
    S TAT E HTTP/1.1 “It is a…stateless protocol” —RFC 2616 (June 1999) cookies sessions form variables URI parameters
  • 44.
    S TAT E Server Owns State Client Server
  • 45.
    S TAT E Request GET / HTTP/1.1 Client Server
  • 46.
    S TAT E Response HTTP/1.1 200 OK Client Server
  • 47.
    S TAT E AJAX asynchronicity Client Server
  • 48.
    S TAT E Infrastructure Client Server
  • 49.
    S TAT E Infrastructure Client Web Server
  • 50.
    S TAT E Infrastructure Client Web Server RESTful Application
  • 51.
    S TAT E Infrastructure Client Web Server RESTful Application Database
  • 52.
    S TAT E Infrastructure Client JavaScript MVC App. Web Server RESTful API / App. Database
  • 53.
    S TAT E Infrastructure Client JavaScript MVC App. Local Storage Bo nu s!
  • 54.
  • 55.
    SPEED JavaScript is Fast Google v8 JS engine —focus on optimizing speed It runs in the browser —cuts out server requests —spares server resources —instantaneous UI
  • 56.
    SPEED Data Transport JSON data only —no markup
  • 57.
    SPEED Data Transport JSON data only —no markup { "id": 1, "first_name": "Philip", "last_name": "Poots", "twitter": "@pootsbook"} vs. "<div id="user_1">n<dl>n<dt>Name</dt> n<dd>Philip Poots</dd>n<dt>Twitter handle:</dt>n<dd>@pootsbook</dd>n</dl> n</div>"
  • 58.
  • 59.
  • 60.