SlideShare a Scribd company logo
1 of 52
Migrating MVC to the
  Front-end using
    Backbone JS
         Martin Drapeau
     CTO & Co-founder Planbox
            Feb 2012



           Martin Drapeau Feb 2012
AGILE PROJECT MANAGEMENT




Based on
SCRUM



              Martin Drapeau Feb 2012
AGILE PROJECT MANAGEMENT




Cloud SAAS
trying to solve
a big
problem...


               Martin Drapeau Feb 2012
Source: www.solutionsiq.com


Martin Drapeau Feb 2012
DEMO TIME!




   Martin Drapeau Feb 2012
AGILE PROJECT MANAGEMENT




   Built on LAMP


         Martin Drapeau Feb 2012
AGILE PROJECT MANAGEMENT




We use
popular
frameworks


                Martin Drapeau Feb 2012
AGILE PROJECT MANAGEMENT




Single Page
Application

Very dynamic

                  Martin Drapeau Feb 2012
AGILE PROJECT MANAGEMENT

                     Client     http://www.planbox.com/plan


                                                      Web Page
                                                            HTML
                                                             CSS

Was architected                      1                    Javascript



on Back-end          Server                           4
                                                                         5

                                    Controller                         View

MVC                                  2
                                     Model

                                     3

                                    Database


                                                 Engine

                Martin Drapeau Feb 2012
The Problem




    Martin Drapeau Feb 2012
MVC in the Back-end
HTML      • HTML generated in PHP
   HTML
HTML      • AJAX to update page
            fragments
          • Javascript is the duck-tape
  HTML




          Feature development
          Bottleneck!

             Martin Drapeau Feb 2012
MVC in the Back-end
        A

B



C




    Change of A requires update of B and C.
    Why does the back-end have to do that?

                        Martin Drapeau Feb 2012
MVC in the Back-end
          does not scale for
         Dynamic Web Apps
WHY?
• Where do I write that code? PHP or JS?
• Can we push to production? No, back-end has
  changed!
• Developers must be trained on PHP and JS.
• Etc...

                   Martin Drapeau Feb 2012
The Solution




    Martin Drapeau Feb 2012
Move MVC to Front-end




 Let’s write our code in Javascript!



              Martin Drapeau Feb 2012
Ground Rules
Back-end
• Becomes a REST API. Talks JSON.
Front-end
• Handles UI interactions.
• Replicates data models.
• Replicates business logic only when necessary.
Must be fast and lightweight!

                    Martin Drapeau Feb 2012
Choose a Framework

Requirements:
• Lightweight - fast to load & mobile friendly
• Extendible
• jQuery Friendly
• Open Source
• Can be integrated gradually


                    Martin Drapeau Feb 2012
Contenders (back in Nov 2010)
      • SproutCore
             A widget framework, too big and constraining!

      • Javascript MVC
             Too much stuff in there! Constraining and awkward.

      • Knockout
             MVVM?? I don’t want to couple views and models!


      • Backbone JS
             Small, has collections, HTML templates, etc. Natural fit.



A recent source of comparisons can be found here:
http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/


                                                         Martin Drapeau Feb 2012
Backbone JS




   Martin Drapeau Feb 2012
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
                                                            Jeremy Ashkenas,
   existing API over a RESTful JSON interface.              Author of
                                                            Backbone JS ,
                                                            Underscore JS, and
                                                            CoffeeScript
                      •Open Source
                      •5.3kb, Packed and gzipped
                      •87 contributors
                      •6,500 watchers
                                  Martin Drapeau Feb 2012
Backbone’s Take on MVC
• Data and presentation are decoupled:
    – “stop tying your data to the DOM”

• Models use the Pub/Sub pattern:
    – Views subscribe to model change events to re-render

• Collections are used to group models:
    – Events bubble up to collections. Subscribe to the add event on the collection
      to get notified.

• Models are synchronized with your back-end:
    – Via AJAX to your RESTful API. CRUD by default.

• Views control user interactions and trigger model updates:
    – HTML templates, jQuery or Zepto DOM manipulation and AJAX

   Where is the C in MVC?              The Controller is in the View.
                                   Martin Drapeau Feb 2012
Model – attributes and events
var story = new Backbone.Model({
    id:1,
    name:"As a coder I want MVC in the front-end",
    points:21
});

story.bind("change:points", function(model, points) {
    console.log("Story #"+model.id+" points changed from "+
        model.previous("points")+" to "+points);
});

story.get("points"); // Returns 21

story.set({points:99});


                                                              Console
>>> Story #1 points changed from 21 to 99

                                    Martin Drapeau Feb 2012
Collection – model IDs and Underscore JS
var stories = new Backbone.Collection([{
     id:1,
     name:"As a coder I want MVC in the front-end",
     points:21
}, {
     id:2,
     name:"As I PM, I want visibility",
     points:33
}]);

var story = stories.get(2); // Return model #2

stories.pluck('points'); // Returns [21, 33]




                             Martin Drapeau Feb 2012
Collection – event bubbling
stories.bind("add", function(collection, model) {
    console.log("Story #"+model.id+" added to collection");
});

stories.add({
    id:3,
    name:"As a driver, I want a reliable car"
    points:5
});

stories.pluck('points'); // Returns [21, 33, 5]




                                                              Console
>>> Story #3 added to collection



                                   Martin Drapeau Feb 2012
Collection – ordered or unordered
stories.pluck('points'); // Returns [21, 33, 5]

stories.comparator = function(modelA, modelB) {
    var a = modelA.get('points');
    var b = modelB.get('points');
    return a < b ? -1 : a > b ? 1 : 0;
}

stories.sort();

stories.pluck('points'); // Returns [5, 21, 33]




                             Martin Drapeau Feb 2012
Collection – fetch from server with AJAX
stories.url = "/api/get_stories"; // REST API

// Preprocess JSON before creating models
stories.parse = function(object) {
    if (object && object.content) return object.content;
};

stories.fetch({
    data: {product_id:1}, // jQuery $.ajax arguments
    dataType: 'JSONP',
    success: function(collection) {
        console.log('Loaded '+collection.length+' stories');
    },
    error: function(collection, error) {
        console.log(error);
    }
});

>>> Loaded 87 stories                                          Console


                             Martin Drapeau Feb 2012
View – Render a model
Use of extend to create a new Class.
StoryView = Backbone.View.extend({
    className: "story",
    render: function() {
        var view = this;
        var model = this.model;
        $(this.el).text(model.get('name'));
        return view; // Always return view for chaining
    }
});

var view = new StoryView({model: story});
view.render();
$(view.el).appendTo('body');




                             Martin Drapeau Feb 2012
View – HTML template (Underscore JS)
<script type="text/template" id="story_template">
    <label>#<%=id%></label>
    <input type="text" value="<%=name%>" />
    <button>Delete</button>
</script>




StoryView = Backbone.View.extend({
    className: "story",
    template: _.template($("#story_template").html()),
    render: function() {
        var view = this;
        var model = this.model;
        $(this.el).html(view.template(model.toJSON()));
        return view;
    }
});


                             Martin Drapeau Feb 2012
View – User interaction
initialize: function() {
    var view = this, model = view.model;
    model.bind("change", view.render, view);
    model.bind("remove", view.remove, view);
    return view;
},
events: { // Delegate events
    "change input": "saveName",
    "click button": "del"
},
saveName: function() {
    var view = this, model = view.model;
    var new_name = $(view.el).children("input").val();
    model.save({name:new_name}); // Call server then model.set
    return view;
},
del: function() {
    var view = this, model = view.model;
    model.destroy(); // Call server then collection remove
    return view;
}

                             Martin Drapeau Feb 2012
Client/Server Sync Loop




   1.   Push changes to server
   2.   Receive acknowledgement
   3.   Set attribute change on data model
   4.   View captures change event
   5.   View renders (maybe)
                     Martin Drapeau Feb 2012
Event Payload – options argument
The options argument can be used as an event payload.
Use it not to render unnecessarily.

saveName: function() {
    var view = this, model = view.model;
    var new_name = $(view.el).children("input").val();
    model.save({name:new_name}, {caller:view});
    return view;
}
render: function(options) {
    options || (options = {});
    if (options.caller == this) return this;

     var view = this;
     var model = this.model;
     $(this.el).html(view.template(model.toJSON()));
     return view;
}


                              Martin Drapeau Feb 2012
View – Render a collection
StoriesView = Backbone.View.extend({
    tagName: "ul",
    className: "stories",
    initialize: function() {
        var view = this;
        var collection = view.collection;
        collection.bind('add', view.addOne, view);
        collection.bind('reset', view.addAll, view);
    },
    addOne: function(model) {
        var view = this;
        var story_view = new StoryView({model: model});
        story_view.render();
        $(view.el).append(story_view.el);
        return view;
    },
    addAll: function() {
        var view = this, collection = view.collection;
        collection.each(function(model) {
            view.addOne(model);
        });
        return view;
    }
});

                                 Martin Drapeau Feb 2012
Other Backbone Artefacts
• Sync
  – Handles client/server communication
  – Uses jQuery (or Zepto) $.ajax
  – Follows CRUD (Model.url and Collection.url)

• Router & History
  – Handle URL changes and that Back button
  – Wraps HTML5 History API
  – Graceful polling fallback

                     Martin Drapeau Feb 2012
Backbone JS
    got
 Planboxed



   Martin Drapeau Feb 2012
No CRUD - Rich verbs mapping to API
• A story model has:
  –   save  www.planbox.com/api/update_story
  –   move  www.planbox.com/api/move_story
  –   duplicate  www.planbox.com/api/duplicate_story
  –   etc...


• Did not use Sync
  – Overwrote methods fetch, save, etc.
  – Used jQuery $.ajax of course

                       Martin Drapeau Feb 2012
Local Persistence in URL
  • State of page is saved in URL’s hash tag using
    JSON (quotes are stripped)

                                   Opened tab in Story
                                                                             Selected Story
                                         Pane


http://planbox.com/nik#{product_id:1,story_pane_tab:tasks,filter_id:1,story_id:199486}



    Top level project
        selected                         Selected Sprint


                                                               https://github.com/martindrapeau/JSON-in-URL-Hash

                                     Martin Drapeau Feb 2012
Model Selection
NikModel = Backbone.Model.extend({
    selected: false,
    select: function(options) {
        options || (options = {});
        if (this.selected) return this;
        this.selected = true;
        if (!options.silent)
            this.trigger('select', this, options);
        return this;
    },
    unselect: function(options) {
        options || (options = {});
        if (!this.selected) return this;
        this.selected = false;
        if (!options.silent)
            this.trigger('unselect', this, options);
        return this;
    }



                             Martin Drapeau Feb 2012
Selection in Collection
NikCollection = Backbone.Collection.extend({
    model: NikModel,
    select: function(model, options) {
        options || (options = {});
        var collection = this;
        _.each(collection.selected(), function(model) {
            model.unselect(options);
        });
        model.select(options);
        return this;
    },
    selected: function() {
        return _.select(this.models, function(model) {
            return model.selected;
        });
    },




                             Martin Drapeau Feb 2012
Collection Filtering
// Argument filters is a hash of attributes and their
// allowed values. For example: filters.type = ['bug']

// Property Model.filtered is a hash of failed conditions.
// For example is Model.type = 'feature', then
// Model.filtered = ['bug'].

Model.filter(filters, options)
Model.filtered // Array of filtered out attributes

Collection.filter() // Runs filtering on the collection
Collection.filtered()
Collection.not_filtered()




                             Martin Drapeau Feb 2012
Sort DOM Against Collection
     DOM                                            Collection
                                                         #199834
                                                         #190293
                                                            #201293
                                                         #150932
                                                         #188456
                                                         #178545
                                                         #190293


• Stories are ordered by priority (same for everyone)
• Need to sync order of stories (i.e. after drag and drop)
• Helper function to re-order DOM elements minimizing DOM
  manipulations



                               Martin Drapeau Feb 2012
Cascading Events – Model bound to Collection




  • Summary Model listens to changes on Stories Collection
  • Keeps sums of points, resources, estimate-hours, etc...
  • Views tied to it update in real time!



                          Martin Drapeau Feb 2012
Custom Widgets
• All widgets are custom
    –   Ligthweight and flexible
    –   Fast to load
    –   No jQuery UI with large CSS and JS footprint
    –   Use of Backbone Models and Collections


• Types of widgets
    –   Dialogs
    –   Drop-downs
    –   Date picker
    –   Auto-complete
    –   Input




                                       Martin Drapeau Feb 2012
Backbone Auto-complete Widget
var collection = new Backbone.Collection([
    {id:"AB", name:"Alberta"},
    {id:"BC", name:"British Columbia"},
    {id:"MB", name:"Manitoba"},
    // ...
    {id:"AP", name:"Armed Forces Pacific"}
]);

$('#states_provinces').autocomplete({
    collection: collection,
    attr: 'name',
    noCase: true,
    ul_class: 'autocomplete shadow',
    ul_css: {'z-index':1234}
});


                   http://www.planbox.com/blog/news/updates/jquery-autocomplete-plugin-for-backbone-js.html




                                    Martin Drapeau Feb 2012
Real Time – No page reload
• Polling server at 15 second interval
  (Tried COMET but was overkill)


• Change history Collection
  – Last transaction ID is kept in client
  – Every 15 seconds, ask server for newer updates
  – Server sends updated Models



                     Martin Drapeau Feb 2012
Deployment
Build procedure
     – Javascript files are minified and collated
     – Version is automatically incremented
     – ?v=3.1234 is added to all CSS/JS files (prevent caching issues)

Planbox - Minifying Javascript Files...
Version: 3.019

3rd.js 70397 bytes                                    hom.js 9758 bytes
jwysiwyg/jquery.wysiwyg.min.js 36278 bytes            acc.js 14505 bytes
zeroclipboard/zeroclipboard.min.js 6747 bytes         rep.js 84129 bytes
adw.js 32136 bytes                                    table.js 42311 bytes
common.js 195872 bytes                                mobile_3rd.js 74594 bytes
nik.js 230008 bytes                                   mobile_common.js 71371 bytes
mag.js 53275 bytes                                    mobile.js 116873 bytes



                                          Martin Drapeau Feb 2012
The Result




   Martin Drapeau Feb 2012
3rd Party Libraries        Application Load Size
                                          JS fileGzipped Size (KB) Content (KB)
                                   jquery.min.js                29.34          83.26
                         jquery.wysiwyg.min.js                  10.54          35.43
                           zeroclipboard.min.js                  2.56           6.59
                                          3rd.js                17.82          68.75
                                                               60.26         194.03

                                    common.js                     41.27      191.28
Application




                                        nik.js                    45.58      224.62
                                                                 86.85        415.9

                                          Total                 147.11       609.93

                      346 Story Models (JSON)                  124.67       949.01
                                     KB/Story                    0.36         2.74



                                             Martin Drapeau Feb 2012
Benefits of MVC in front-end
• Decouple back-end and front-end
  – The API becomes the back-end contract (and
    performance too I hope).
  – Back-end and front-end teams are decoupled

• Bandwidth reduction
  – Data and presentation loaded once
  – Subsequently, only Model deltas are transferred

• Reduce server load
  – All UX processing is performed client side

                        Martin Drapeau Feb 2012
Benefits of MVC in front-end
• Release anytime
   – Majority of code changes are in UI
   – Changes happen faster in front-end than back-end
   – Concurrent versions of the client can exist. Hit F5 to get the
     latest and greatest.
   – Back-end doesn’t change – no risk of conflicts in browser

• Faster development
   – Know and master one language
   – Use the browser as your development and testing bed (yeah
     Firebug!)
   – Release often
   – Don’t accumulate ‘corrected’ defects in development – push
     them out as they are fixed

                             Martin Drapeau Feb 2012
Acknowledgements

Mathieu Dumais-Savard
  Sébastien Giroux
  Jeremy Ashkenas
   js-montreal.org




       Martin Drapeau Feb 2012
References & Links
Javascript Frameworks
•   Backbone JS http://documentcloud.github.com/backbone/
•   JavascriptMVC http://javascriptmvc.com/
•   SproutCore http://sproutcore.com/
•   Underscore JS http://documentcloud.github.com/underscore/
•   jQuery http://jquery.com/

Helpers
•   John Resig’s Javascript Micro-Template http://ejohn.org/blog/javascript-micro-templating/
•   JSON2 http://www.json.org/js.html
•   jsmin (PHP minifier) https://github.com/rgrove/jsmin-php/

Books
•   JavasScript Web Applications (Alex MaxCaw) http://shop.oreilly.com/product/0636920018421.do
•   jQuery Cookbook (Cody Lindley) http://shop.oreilly.com/product/9780596159788.do?sortby=bestSellers

Planbox Open Source Contributions
•   Backbone Widgets https://github.com/martindrapeau/Backbone-Widgets
•   JSON in URL Hash https://github.com/martindrapeau/JSON-in-URL-Hash


                                             Martin Drapeau Feb 2012
Questions?



   Martin Drapeau Feb 2012

More Related Content

What's hot

Viking academy backbone.js
Viking academy  backbone.jsViking academy  backbone.js
Viking academy backbone.jsBert Wijnants
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceParashuram N
 
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...Atlassian
 
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...Atlassian
 
Introducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and serverIntroducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and serverSpike Brehm
 
Backbone js in action
Backbone js in actionBackbone js in action
Backbone js in actionUsha Guduri
 
AngularJS for designers and developers
AngularJS for designers and developersAngularJS for designers and developers
AngularJS for designers and developersKai Koenig
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications  Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications Juliana Lucena
 
How to migrate Cakephp 1.x to 2.x
How to migrate Cakephp 1.x to 2.xHow to migrate Cakephp 1.x to 2.x
How to migrate Cakephp 1.x to 2.xAndolasoft Inc
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rulesSrijan Technologies
 
Using RequireJS with CakePHP
Using RequireJS with CakePHPUsing RequireJS with CakePHP
Using RequireJS with CakePHPStephen Young
 
Workshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSWorkshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSVisual Engineering
 
Angular JS blog tutorial
Angular JS blog tutorialAngular JS blog tutorial
Angular JS blog tutorialClaude Tech
 
AngularJS Directives
AngularJS DirectivesAngularJS Directives
AngularJS DirectivesEyal Vardi
 
Upgrade your javascript to drupal 8
Upgrade your javascript to drupal 8Upgrade your javascript to drupal 8
Upgrade your javascript to drupal 8Théodore Biadala
 
jQuery and_drupal
jQuery and_drupaljQuery and_drupal
jQuery and_drupalBlackCatWeb
 

What's hot (20)

Viking academy backbone.js
Viking academy  backbone.jsViking academy  backbone.js
Viking academy backbone.js
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and Performance
 
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
 
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
 
Introducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and serverIntroducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and server
 
Backbone js in action
Backbone js in actionBackbone js in action
Backbone js in action
 
AngularJS for designers and developers
AngularJS for designers and developersAngularJS for designers and developers
AngularJS for designers and developers
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications  Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications
 
How to migrate Cakephp 1.x to 2.x
How to migrate Cakephp 1.x to 2.xHow to migrate Cakephp 1.x to 2.x
How to migrate Cakephp 1.x to 2.x
 
Sane Async Patterns
Sane Async PatternsSane Async Patterns
Sane Async Patterns
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
 
AngularJS Basic Training
AngularJS Basic TrainingAngularJS Basic Training
AngularJS Basic Training
 
Using RequireJS with CakePHP
Using RequireJS with CakePHPUsing RequireJS with CakePHP
Using RequireJS with CakePHP
 
Workshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSWorkshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJS
 
Angular js
Angular jsAngular js
Angular js
 
Angular JS blog tutorial
Angular JS blog tutorialAngular JS blog tutorial
Angular JS blog tutorial
 
AngularJS Directives
AngularJS DirectivesAngularJS Directives
AngularJS Directives
 
The AngularJS way
The AngularJS wayThe AngularJS way
The AngularJS way
 
Upgrade your javascript to drupal 8
Upgrade your javascript to drupal 8Upgrade your javascript to drupal 8
Upgrade your javascript to drupal 8
 
jQuery and_drupal
jQuery and_drupaljQuery and_drupal
jQuery and_drupal
 

Viewers also liked

Build your website with awestruct and publish it on the cloud with git
Build your website with awestruct and publish it on the cloud with gitBuild your website with awestruct and publish it on the cloud with git
Build your website with awestruct and publish it on the cloud with gitXavier Coulon
 
Mobile megatrends 2011 (VisionMobile)
Mobile megatrends 2011 (VisionMobile)Mobile megatrends 2011 (VisionMobile)
Mobile megatrends 2011 (VisionMobile)SlashData
 
33 "Must-Do" Tips to Improve HTML Email Design
33 "Must-Do" Tips to Improve HTML Email Design33 "Must-Do" Tips to Improve HTML Email Design
33 "Must-Do" Tips to Improve HTML Email DesignPinpointe On-Demand
 
Friends Don't Let Friends Clap on One and Three: a Backbeat Clapping Study
Friends Don't Let Friends Clap on One and Three: a Backbeat Clapping StudyFriends Don't Let Friends Clap on One and Three: a Backbeat Clapping Study
Friends Don't Let Friends Clap on One and Three: a Backbeat Clapping StudyEthan Hein
 
Love and Loss: A Symfony Security Play
Love and Loss: A Symfony Security PlayLove and Loss: A Symfony Security Play
Love and Loss: A Symfony Security PlayKris Wallsmith
 
The User Experience Brief
The User Experience BriefThe User Experience Brief
The User Experience BriefJohn Yesko
 
Google Analytics Bag O' Tricks
Google Analytics Bag O' TricksGoogle Analytics Bag O' Tricks
Google Analytics Bag O' TricksSimo Ahava
 
Liite 08 sote makudigin muutosorganisonti ja toimeenpanon projektointi
Liite 08 sote makudigin muutosorganisonti ja toimeenpanon projektointiLiite 08 sote makudigin muutosorganisonti ja toimeenpanon projektointi
Liite 08 sote makudigin muutosorganisonti ja toimeenpanon projektointiSinikka Pennanen
 

Viewers also liked (9)

Build your website with awestruct and publish it on the cloud with git
Build your website with awestruct and publish it on the cloud with gitBuild your website with awestruct and publish it on the cloud with git
Build your website with awestruct and publish it on the cloud with git
 
Mobile megatrends 2011 (VisionMobile)
Mobile megatrends 2011 (VisionMobile)Mobile megatrends 2011 (VisionMobile)
Mobile megatrends 2011 (VisionMobile)
 
33 "Must-Do" Tips to Improve HTML Email Design
33 "Must-Do" Tips to Improve HTML Email Design33 "Must-Do" Tips to Improve HTML Email Design
33 "Must-Do" Tips to Improve HTML Email Design
 
Friends Don't Let Friends Clap on One and Three: a Backbeat Clapping Study
Friends Don't Let Friends Clap on One and Three: a Backbeat Clapping StudyFriends Don't Let Friends Clap on One and Three: a Backbeat Clapping Study
Friends Don't Let Friends Clap on One and Three: a Backbeat Clapping Study
 
Love and Loss: A Symfony Security Play
Love and Loss: A Symfony Security PlayLove and Loss: A Symfony Security Play
Love and Loss: A Symfony Security Play
 
The User Experience Brief
The User Experience BriefThe User Experience Brief
The User Experience Brief
 
Google Analytics Bag O' Tricks
Google Analytics Bag O' TricksGoogle Analytics Bag O' Tricks
Google Analytics Bag O' Tricks
 
Liite 08 sote makudigin muutosorganisonti ja toimeenpanon projektointi
Liite 08 sote makudigin muutosorganisonti ja toimeenpanon projektointiLiite 08 sote makudigin muutosorganisonti ja toimeenpanon projektointi
Liite 08 sote makudigin muutosorganisonti ja toimeenpanon projektointi
 
Linuxシステム管理入門
Linuxシステム管理入門Linuxシステム管理入門
Linuxシステム管理入門
 

Similar to Planbox Backbone MVC

MV* presentation frameworks in Javascript: en garde, pret, allez!
MV* presentation frameworks in Javascript: en garde, pret, allez!MV* presentation frameworks in Javascript: en garde, pret, allez!
MV* presentation frameworks in Javascript: en garde, pret, allez!Roberto Messora
 
Rp 6 session 2 naresh bhatia
Rp 6  session 2 naresh bhatiaRp 6  session 2 naresh bhatia
Rp 6 session 2 naresh bhatiasapientindia
 
MVC Demystified: Essence of Ruby on Rails
MVC Demystified: Essence of Ruby on RailsMVC Demystified: Essence of Ruby on Rails
MVC Demystified: Essence of Ruby on Railscodeinmotion
 
From Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) AgainFrom Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) Againjonknapp
 
Modelibra Software Family
Modelibra Software FamilyModelibra Software Family
Modelibra Software Familydzenanr
 
Introduction To Code Igniter
Introduction To Code IgniterIntroduction To Code Igniter
Introduction To Code IgniterAmzad Hossain
 
MuleSoft Surat Virtual Meetup#6 - MuleSoft Project Template Using Maven Arche...
MuleSoft Surat Virtual Meetup#6 - MuleSoft Project Template Using Maven Arche...MuleSoft Surat Virtual Meetup#6 - MuleSoft Project Template Using Maven Arche...
MuleSoft Surat Virtual Meetup#6 - MuleSoft Project Template Using Maven Arche...Jitendra Bafna
 
AEM Sightly Deep Dive
AEM Sightly Deep DiveAEM Sightly Deep Dive
AEM Sightly Deep DiveGabriel Walt
 
Web applications with Catalyst
Web applications with CatalystWeb applications with Catalyst
Web applications with Catalystsvilen.ivanov
 
Javascript frameworks: Backbone.js
Javascript frameworks: Backbone.jsJavascript frameworks: Backbone.js
Javascript frameworks: Backbone.jsSoós Gábor
 
MVC Design Pattern in JavaScript by ADMEC Multimedia Institute
MVC Design Pattern in JavaScript by ADMEC Multimedia InstituteMVC Design Pattern in JavaScript by ADMEC Multimedia Institute
MVC Design Pattern in JavaScript by ADMEC Multimedia InstituteRavi Bhadauria
 
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...Sparkhound Inc.
 
Spring MVC Intro / Gore - Nov NHJUG
Spring MVC Intro / Gore - Nov NHJUGSpring MVC Intro / Gore - Nov NHJUG
Spring MVC Intro / Gore - Nov NHJUGTed Pennings
 
using Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'susing Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'sAntônio Roberto Silva
 
SnapyX
SnapyXSnapyX
SnapyXekino
 
Developing Java Web Applications
Developing Java Web ApplicationsDeveloping Java Web Applications
Developing Java Web Applicationshchen1
 

Similar to Planbox Backbone MVC (20)

MVC & backbone.js
MVC & backbone.jsMVC & backbone.js
MVC & backbone.js
 
MV* presentation frameworks in Javascript: en garde, pret, allez!
MV* presentation frameworks in Javascript: en garde, pret, allez!MV* presentation frameworks in Javascript: en garde, pret, allez!
MV* presentation frameworks in Javascript: en garde, pret, allez!
 
Rp 6 session 2 naresh bhatia
Rp 6  session 2 naresh bhatiaRp 6  session 2 naresh bhatia
Rp 6 session 2 naresh bhatia
 
MVC Demystified: Essence of Ruby on Rails
MVC Demystified: Essence of Ruby on RailsMVC Demystified: Essence of Ruby on Rails
MVC Demystified: Essence of Ruby on Rails
 
Fundaments of Knockout js
Fundaments of Knockout jsFundaments of Knockout js
Fundaments of Knockout js
 
From Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) AgainFrom Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) Again
 
Modelibra Software Family
Modelibra Software FamilyModelibra Software Family
Modelibra Software Family
 
Introduction To Code Igniter
Introduction To Code IgniterIntroduction To Code Igniter
Introduction To Code Igniter
 
MuleSoft Surat Virtual Meetup#6 - MuleSoft Project Template Using Maven Arche...
MuleSoft Surat Virtual Meetup#6 - MuleSoft Project Template Using Maven Arche...MuleSoft Surat Virtual Meetup#6 - MuleSoft Project Template Using Maven Arche...
MuleSoft Surat Virtual Meetup#6 - MuleSoft Project Template Using Maven Arche...
 
Building richwebapplicationsusingasp
Building richwebapplicationsusingaspBuilding richwebapplicationsusingasp
Building richwebapplicationsusingasp
 
AEM Sightly Deep Dive
AEM Sightly Deep DiveAEM Sightly Deep Dive
AEM Sightly Deep Dive
 
Web applications with Catalyst
Web applications with CatalystWeb applications with Catalyst
Web applications with Catalyst
 
Javascript frameworks: Backbone.js
Javascript frameworks: Backbone.jsJavascript frameworks: Backbone.js
Javascript frameworks: Backbone.js
 
MVC Design Pattern in JavaScript by ADMEC Multimedia Institute
MVC Design Pattern in JavaScript by ADMEC Multimedia InstituteMVC Design Pattern in JavaScript by ADMEC Multimedia Institute
MVC Design Pattern in JavaScript by ADMEC Multimedia Institute
 
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...
 
Spring MVC Intro / Gore - Nov NHJUG
Spring MVC Intro / Gore - Nov NHJUGSpring MVC Intro / Gore - Nov NHJUG
Spring MVC Intro / Gore - Nov NHJUG
 
using Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'susing Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API's
 
SnapyX
SnapyXSnapyX
SnapyX
 
SnapyX - ParisJS
SnapyX - ParisJSSnapyX - ParisJS
SnapyX - ParisJS
 
Developing Java Web Applications
Developing Java Web ApplicationsDeveloping Java Web Applications
Developing Java Web Applications
 

Recently uploaded

Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 

Recently uploaded (20)

Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 

Planbox Backbone MVC

  • 1. Migrating MVC to the Front-end using Backbone JS Martin Drapeau CTO & Co-founder Planbox Feb 2012 Martin Drapeau Feb 2012
  • 2. AGILE PROJECT MANAGEMENT Based on SCRUM Martin Drapeau Feb 2012
  • 3. AGILE PROJECT MANAGEMENT Cloud SAAS trying to solve a big problem... Martin Drapeau Feb 2012
  • 5. DEMO TIME! Martin Drapeau Feb 2012
  • 6. AGILE PROJECT MANAGEMENT Built on LAMP Martin Drapeau Feb 2012
  • 7. AGILE PROJECT MANAGEMENT We use popular frameworks Martin Drapeau Feb 2012
  • 8. AGILE PROJECT MANAGEMENT Single Page Application Very dynamic Martin Drapeau Feb 2012
  • 9. AGILE PROJECT MANAGEMENT Client http://www.planbox.com/plan Web Page HTML CSS Was architected 1 Javascript on Back-end Server 4 5 Controller View MVC 2 Model 3 Database Engine Martin Drapeau Feb 2012
  • 10. The Problem Martin Drapeau Feb 2012
  • 11. MVC in the Back-end HTML • HTML generated in PHP HTML HTML • AJAX to update page fragments • Javascript is the duck-tape HTML Feature development Bottleneck! Martin Drapeau Feb 2012
  • 12. MVC in the Back-end A B C Change of A requires update of B and C. Why does the back-end have to do that? Martin Drapeau Feb 2012
  • 13. MVC in the Back-end does not scale for Dynamic Web Apps WHY? • Where do I write that code? PHP or JS? • Can we push to production? No, back-end has changed! • Developers must be trained on PHP and JS. • Etc... Martin Drapeau Feb 2012
  • 14. The Solution Martin Drapeau Feb 2012
  • 15. Move MVC to Front-end Let’s write our code in Javascript! Martin Drapeau Feb 2012
  • 16. Ground Rules Back-end • Becomes a REST API. Talks JSON. Front-end • Handles UI interactions. • Replicates data models. • Replicates business logic only when necessary. Must be fast and lightweight! Martin Drapeau Feb 2012
  • 17. Choose a Framework Requirements: • Lightweight - fast to load & mobile friendly • Extendible • jQuery Friendly • Open Source • Can be integrated gradually Martin Drapeau Feb 2012
  • 18. Contenders (back in Nov 2010) • SproutCore A widget framework, too big and constraining! • Javascript MVC Too much stuff in there! Constraining and awkward. • Knockout MVVM?? I don’t want to couple views and models! • Backbone JS Small, has collections, HTML templates, etc. Natural fit. A recent source of comparisons can be found here: http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/ Martin Drapeau Feb 2012
  • 19. Backbone JS Martin Drapeau Feb 2012
  • 20. 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 Jeremy Ashkenas, existing API over a RESTful JSON interface. Author of Backbone JS , Underscore JS, and CoffeeScript •Open Source •5.3kb, Packed and gzipped •87 contributors •6,500 watchers Martin Drapeau Feb 2012
  • 21. Backbone’s Take on MVC • Data and presentation are decoupled: – “stop tying your data to the DOM” • Models use the Pub/Sub pattern: – Views subscribe to model change events to re-render • Collections are used to group models: – Events bubble up to collections. Subscribe to the add event on the collection to get notified. • Models are synchronized with your back-end: – Via AJAX to your RESTful API. CRUD by default. • Views control user interactions and trigger model updates: – HTML templates, jQuery or Zepto DOM manipulation and AJAX Where is the C in MVC? The Controller is in the View. Martin Drapeau Feb 2012
  • 22. Model – attributes and events var story = new Backbone.Model({ id:1, name:"As a coder I want MVC in the front-end", points:21 }); story.bind("change:points", function(model, points) { console.log("Story #"+model.id+" points changed from "+ model.previous("points")+" to "+points); }); story.get("points"); // Returns 21 story.set({points:99}); Console >>> Story #1 points changed from 21 to 99 Martin Drapeau Feb 2012
  • 23. Collection – model IDs and Underscore JS var stories = new Backbone.Collection([{ id:1, name:"As a coder I want MVC in the front-end", points:21 }, { id:2, name:"As I PM, I want visibility", points:33 }]); var story = stories.get(2); // Return model #2 stories.pluck('points'); // Returns [21, 33] Martin Drapeau Feb 2012
  • 24. Collection – event bubbling stories.bind("add", function(collection, model) { console.log("Story #"+model.id+" added to collection"); }); stories.add({ id:3, name:"As a driver, I want a reliable car" points:5 }); stories.pluck('points'); // Returns [21, 33, 5] Console >>> Story #3 added to collection Martin Drapeau Feb 2012
  • 25. Collection – ordered or unordered stories.pluck('points'); // Returns [21, 33, 5] stories.comparator = function(modelA, modelB) { var a = modelA.get('points'); var b = modelB.get('points'); return a < b ? -1 : a > b ? 1 : 0; } stories.sort(); stories.pluck('points'); // Returns [5, 21, 33] Martin Drapeau Feb 2012
  • 26. Collection – fetch from server with AJAX stories.url = "/api/get_stories"; // REST API // Preprocess JSON before creating models stories.parse = function(object) { if (object && object.content) return object.content; }; stories.fetch({ data: {product_id:1}, // jQuery $.ajax arguments dataType: 'JSONP', success: function(collection) { console.log('Loaded '+collection.length+' stories'); }, error: function(collection, error) { console.log(error); } }); >>> Loaded 87 stories Console Martin Drapeau Feb 2012
  • 27. View – Render a model Use of extend to create a new Class. StoryView = Backbone.View.extend({ className: "story", render: function() { var view = this; var model = this.model; $(this.el).text(model.get('name')); return view; // Always return view for chaining } }); var view = new StoryView({model: story}); view.render(); $(view.el).appendTo('body'); Martin Drapeau Feb 2012
  • 28. View – HTML template (Underscore JS) <script type="text/template" id="story_template"> <label>#<%=id%></label> <input type="text" value="<%=name%>" /> <button>Delete</button> </script> StoryView = Backbone.View.extend({ className: "story", template: _.template($("#story_template").html()), render: function() { var view = this; var model = this.model; $(this.el).html(view.template(model.toJSON())); return view; } }); Martin Drapeau Feb 2012
  • 29. View – User interaction initialize: function() { var view = this, model = view.model; model.bind("change", view.render, view); model.bind("remove", view.remove, view); return view; }, events: { // Delegate events "change input": "saveName", "click button": "del" }, saveName: function() { var view = this, model = view.model; var new_name = $(view.el).children("input").val(); model.save({name:new_name}); // Call server then model.set return view; }, del: function() { var view = this, model = view.model; model.destroy(); // Call server then collection remove return view; } Martin Drapeau Feb 2012
  • 30. Client/Server Sync Loop 1. Push changes to server 2. Receive acknowledgement 3. Set attribute change on data model 4. View captures change event 5. View renders (maybe) Martin Drapeau Feb 2012
  • 31. Event Payload – options argument The options argument can be used as an event payload. Use it not to render unnecessarily. saveName: function() { var view = this, model = view.model; var new_name = $(view.el).children("input").val(); model.save({name:new_name}, {caller:view}); return view; } render: function(options) { options || (options = {}); if (options.caller == this) return this; var view = this; var model = this.model; $(this.el).html(view.template(model.toJSON())); return view; } Martin Drapeau Feb 2012
  • 32. View – Render a collection StoriesView = Backbone.View.extend({ tagName: "ul", className: "stories", initialize: function() { var view = this; var collection = view.collection; collection.bind('add', view.addOne, view); collection.bind('reset', view.addAll, view); }, addOne: function(model) { var view = this; var story_view = new StoryView({model: model}); story_view.render(); $(view.el).append(story_view.el); return view; }, addAll: function() { var view = this, collection = view.collection; collection.each(function(model) { view.addOne(model); }); return view; } }); Martin Drapeau Feb 2012
  • 33. Other Backbone Artefacts • Sync – Handles client/server communication – Uses jQuery (or Zepto) $.ajax – Follows CRUD (Model.url and Collection.url) • Router & History – Handle URL changes and that Back button – Wraps HTML5 History API – Graceful polling fallback Martin Drapeau Feb 2012
  • 34. Backbone JS got Planboxed Martin Drapeau Feb 2012
  • 35. No CRUD - Rich verbs mapping to API • A story model has: – save  www.planbox.com/api/update_story – move  www.planbox.com/api/move_story – duplicate  www.planbox.com/api/duplicate_story – etc... • Did not use Sync – Overwrote methods fetch, save, etc. – Used jQuery $.ajax of course Martin Drapeau Feb 2012
  • 36. Local Persistence in URL • State of page is saved in URL’s hash tag using JSON (quotes are stripped) Opened tab in Story Selected Story Pane http://planbox.com/nik#{product_id:1,story_pane_tab:tasks,filter_id:1,story_id:199486} Top level project selected Selected Sprint https://github.com/martindrapeau/JSON-in-URL-Hash Martin Drapeau Feb 2012
  • 37. Model Selection NikModel = Backbone.Model.extend({ selected: false, select: function(options) { options || (options = {}); if (this.selected) return this; this.selected = true; if (!options.silent) this.trigger('select', this, options); return this; }, unselect: function(options) { options || (options = {}); if (!this.selected) return this; this.selected = false; if (!options.silent) this.trigger('unselect', this, options); return this; } Martin Drapeau Feb 2012
  • 38. Selection in Collection NikCollection = Backbone.Collection.extend({ model: NikModel, select: function(model, options) { options || (options = {}); var collection = this; _.each(collection.selected(), function(model) { model.unselect(options); }); model.select(options); return this; }, selected: function() { return _.select(this.models, function(model) { return model.selected; }); }, Martin Drapeau Feb 2012
  • 39. Collection Filtering // Argument filters is a hash of attributes and their // allowed values. For example: filters.type = ['bug'] // Property Model.filtered is a hash of failed conditions. // For example is Model.type = 'feature', then // Model.filtered = ['bug']. Model.filter(filters, options) Model.filtered // Array of filtered out attributes Collection.filter() // Runs filtering on the collection Collection.filtered() Collection.not_filtered() Martin Drapeau Feb 2012
  • 40. Sort DOM Against Collection DOM Collection #199834 #190293 #201293 #150932 #188456 #178545 #190293 • Stories are ordered by priority (same for everyone) • Need to sync order of stories (i.e. after drag and drop) • Helper function to re-order DOM elements minimizing DOM manipulations Martin Drapeau Feb 2012
  • 41. Cascading Events – Model bound to Collection • Summary Model listens to changes on Stories Collection • Keeps sums of points, resources, estimate-hours, etc... • Views tied to it update in real time! Martin Drapeau Feb 2012
  • 42. Custom Widgets • All widgets are custom – Ligthweight and flexible – Fast to load – No jQuery UI with large CSS and JS footprint – Use of Backbone Models and Collections • Types of widgets – Dialogs – Drop-downs – Date picker – Auto-complete – Input Martin Drapeau Feb 2012
  • 43. Backbone Auto-complete Widget var collection = new Backbone.Collection([ {id:"AB", name:"Alberta"}, {id:"BC", name:"British Columbia"}, {id:"MB", name:"Manitoba"}, // ... {id:"AP", name:"Armed Forces Pacific"} ]); $('#states_provinces').autocomplete({ collection: collection, attr: 'name', noCase: true, ul_class: 'autocomplete shadow', ul_css: {'z-index':1234} }); http://www.planbox.com/blog/news/updates/jquery-autocomplete-plugin-for-backbone-js.html Martin Drapeau Feb 2012
  • 44. Real Time – No page reload • Polling server at 15 second interval (Tried COMET but was overkill) • Change history Collection – Last transaction ID is kept in client – Every 15 seconds, ask server for newer updates – Server sends updated Models Martin Drapeau Feb 2012
  • 45. Deployment Build procedure – Javascript files are minified and collated – Version is automatically incremented – ?v=3.1234 is added to all CSS/JS files (prevent caching issues) Planbox - Minifying Javascript Files... Version: 3.019 3rd.js 70397 bytes hom.js 9758 bytes jwysiwyg/jquery.wysiwyg.min.js 36278 bytes acc.js 14505 bytes zeroclipboard/zeroclipboard.min.js 6747 bytes rep.js 84129 bytes adw.js 32136 bytes table.js 42311 bytes common.js 195872 bytes mobile_3rd.js 74594 bytes nik.js 230008 bytes mobile_common.js 71371 bytes mag.js 53275 bytes mobile.js 116873 bytes Martin Drapeau Feb 2012
  • 46. The Result Martin Drapeau Feb 2012
  • 47. 3rd Party Libraries Application Load Size JS fileGzipped Size (KB) Content (KB) jquery.min.js 29.34 83.26 jquery.wysiwyg.min.js 10.54 35.43 zeroclipboard.min.js 2.56 6.59 3rd.js 17.82 68.75 60.26 194.03 common.js 41.27 191.28 Application nik.js 45.58 224.62 86.85 415.9 Total 147.11 609.93 346 Story Models (JSON) 124.67 949.01 KB/Story 0.36 2.74 Martin Drapeau Feb 2012
  • 48. Benefits of MVC in front-end • Decouple back-end and front-end – The API becomes the back-end contract (and performance too I hope). – Back-end and front-end teams are decoupled • Bandwidth reduction – Data and presentation loaded once – Subsequently, only Model deltas are transferred • Reduce server load – All UX processing is performed client side Martin Drapeau Feb 2012
  • 49. Benefits of MVC in front-end • Release anytime – Majority of code changes are in UI – Changes happen faster in front-end than back-end – Concurrent versions of the client can exist. Hit F5 to get the latest and greatest. – Back-end doesn’t change – no risk of conflicts in browser • Faster development – Know and master one language – Use the browser as your development and testing bed (yeah Firebug!) – Release often – Don’t accumulate ‘corrected’ defects in development – push them out as they are fixed Martin Drapeau Feb 2012
  • 50. Acknowledgements Mathieu Dumais-Savard Sébastien Giroux Jeremy Ashkenas js-montreal.org Martin Drapeau Feb 2012
  • 51. References & Links Javascript Frameworks • Backbone JS http://documentcloud.github.com/backbone/ • JavascriptMVC http://javascriptmvc.com/ • SproutCore http://sproutcore.com/ • Underscore JS http://documentcloud.github.com/underscore/ • jQuery http://jquery.com/ Helpers • John Resig’s Javascript Micro-Template http://ejohn.org/blog/javascript-micro-templating/ • JSON2 http://www.json.org/js.html • jsmin (PHP minifier) https://github.com/rgrove/jsmin-php/ Books • JavasScript Web Applications (Alex MaxCaw) http://shop.oreilly.com/product/0636920018421.do • jQuery Cookbook (Cody Lindley) http://shop.oreilly.com/product/9780596159788.do?sortby=bestSellers Planbox Open Source Contributions • Backbone Widgets https://github.com/martindrapeau/Backbone-Widgets • JSON in URL Hash https://github.com/martindrapeau/JSON-in-URL-Hash Martin Drapeau Feb 2012
  • 52. Questions? Martin Drapeau Feb 2012