SlideShare a Scribd company logo
A Little


For Your App
   Luca Mearelli
var Luca = (function(){
    var me = {};
     me.is = 'craftsman';
     me.twitter = '@lmea';
     me.did = ['http://miojob.repubblica.it',
               'http://kiaraservice.com',
               '...'];
    me.uses = function(tool){
         _.indexOf(['ruby', 'rails', 'javascript'], tool)>=0;
     }
    me.used = function(tool){
         _.indexOf(['c++', 'python', 'java'], tool)>=0;
     }
    return me;
})()




                                        @lmea #jsday     http://joind.in/3360
http://github.com/documentcloud/backbone/




                          @lmea #jsday   http://joind.in/3360
A quick poll




           Using DOM libraries?
           Using (end-to-end) frameworks?
           Know or used backbone.js?




                                  @lmea #jsday   http://joind.in/3360
Backbone.js: what is it?




           A lightweight collection of tools
           giving enough structure to help
           building apps in the browser
           without getting in the way



                                @lmea #jsday   http://joind.in/3360
Backbone.js: what is it for?




           Data heavy pages
           Frontends to (JSON) web services
           CRUD-kind web apps




                                @lmea #jsday   http://joind.in/3360
Backbone.js: Model-View-Controller




                                     model




                view                            controller




                                             @lmea #jsday    http://joind.in/3360
Elements of backbone




          Model
          Collection
          View
          Controller


                       @lmea #jsday   http://joind.in/3360
Elements of backbone (2)




          Event
          Sync
          History


                           @lmea #jsday   http://joind.in/3360
Model & Collection




          Representing the data
          Building the business logic
          Handling persistence




                                 @lmea #jsday   http://joind.in/3360
The simplest model




     var Talk = Backbone.Model.extend({})




                                            @lmea #jsday   http://joind.in/3360
Initializing & setting defaults




       var Talk = Backbone.Model.extend({

            // Default attributes for Talk
            defaults: {
               title: "a talk",
               speaker: "me",
               lenght: 60
            },

            intialize: function(){
              if (this.length>10) {
                 this.set({"lightining": false});
               }
            },
       })




                                                    @lmea #jsday   http://joind.in/3360
Assorted CRUD methods




     var my_talk = new Talk({title: "A Little Backbone"});

     my_talk.get("title");
     my_talk.set({"speaker":"Luca Mearelli"});

     if(my_talk.has("video")){
        //...
     };

     my_talk.unset("speaker")
     my_talk.id
     my_talk.cid




                                            @lmea #jsday     http://joind.in/3360
Custom functions




     var Talk = Backbone.Model.extend({

          full_info: function(){
            return this.get("title")+" by:"+this.get("speaker");
          },

          rate: function(stars){
            if(_.isUndefined(this.get("rating"))){
               this.save({rating: stars});
             }
          },

     })




                                               @lmea #jsday    http://joind.in/3360
Validating models



      var Talk = Backbone.Model.extend({

        validate: function(attrs) {
          if (_.isEmpty(attrs.title)) {
            return "The title should be defined";
          }
          if (attrs.lenght>60) {
            return "The maximum lenght is 60 minutes";
          }
        }

      });

      my_talk.bind("error", function(model, error) {
        alert(model.full_info() + " " + error);
      });
      my_talk.set({"lenght":120});




                                             @lmea #jsday   http://joind.in/3360
Saving models




      // delegates to Backbone.sync
      my_talk.save(); // if my_talk.isNew() -> ‘create’ (HTTP “POST”)
      my_talk.save({title:"ahah"}) // otherwise ‘update’ (HTTP “PUT”)

      my_talk.save({...},
                   {
                      success: function(model, resp, xhr){...},
                      error: function(model, errormsg){...}
                   });

      my_talk.url(); // /[collection.url]/[id] or /[urlRoot]/[id]
      Talk.urlRoot = '/talks';




                                             @lmea #jsday    http://joind.in/3360
Backbone.sync




   Backbone.sync = function(method, model, options) {

        switch   (method) {
          case   "read":    ...   break;   //   read !   GET    /collection[/id]
          case   "create": ...    break;   //   create   ! POST    /collection
          case   "update": ...    break;   //   update   ! PUT    /collection/id
          case   "delete": ...    break;   //   delete   ! DELETE    /collection/id
        }

   };

   // to emulate put & delete with post + parameter
   Backbone.emulateHTTP = true;




                                                          @lmea #jsday     http://joind.in/3360
Models collection




      var Track = Backbone.Collection.extend({
        model: Talk
      });

      var track_talks = new Track([talk1, talk2, talk3]);
      track_talks.get(talk2.id); // gets talk2
      track_talks.at(0); // gets talk1
      track_talks.lenght; // is 3




                                             @lmea #jsday   http://joind.in/3360
Collection: adding and removing models




   track_talks.add(
      {title:"JavaScript Survival Guide",speaker:"Giordano Scalzo " }
   );
   track_talks.add([
      {title: "Faster Web Sites 2.0", speaker: "Steve Souders" },
      {title: "HTML5, the current status", speaker:"Patrick H. Lauke"}
   ]);

   track_talks.remove(talk1);
   track_talks.remove([talk2, talk3]);

   track_talks.refresh([
     {title:"Javascript the New Parts",speaker: "Federico Galassi" }
   ]);




                                             @lmea #jsday    http://joind.in/3360
Fetching a collection from the server




      var Track = Backbone.Collection.extend({
        url: function(){
          return "/tracks/"+this.get("number");
        },
        // or simply url: "/talks"
      });

      var track_talks = new Track({number: 1})
      track_talks.fetch(); // calls model.parse(response)




                                             @lmea #jsday   http://joind.in/3360
Custom sorted collections




     track_talks.comparator = function(talk) {
       return talk.get("time");
     }

     track_talks.add(new Talk({time: 17,
                               title: "A Little Backbone"}));

     track_talks.add(new Talk({time: 9,
                               title: "Faster Web Sites 2.0"}));

     track_talks.add(new Talk({time: 10,
                               title: "JavaScript Survival Guide"}));

     alert(track_talks.pluck('title'));

     track_talks.sort();




                                             @lmea #jsday       http://joind.in/3360
Underscore.js goodies



     var Track = Backbone.Collection.extend({

       future: function() {
         return this.filter(function(talk){
                   return todo.get('time')>(new Date()).getHours();
                });
       },

       next: function() {
         return this.first.apply(this, this.future());
       }
       // forEach (each), map, reduce (foldl, inject),
       // reduceRight (foldr), find (detect), filter (select),
       // reject, every (all), some (any), include, invoke, max,
       // min, sortBy, sortedIndex, toArray, size, first, rest,
       // last, without, indexOf, lastIndexOf, isEmpty, chain
     });




                                                @lmea #jsday   http://joind.in/3360
Views




        is a small chunk of the page
        has declarative event handling
        acts like a view controller




                              @lmea #jsday   http://joind.in/3360
A basic view



     // The DOM element for a talk
     var TalkView = Backbone.View.extend({

       //... is a div tag.
       tagName: "div",
       className: "a-talk-row",

       render: function() {
         $(this.el).html(this.model.full_info());
         return this;
       },
     });

     v = new TalkView({
           model:my_talk,
           id: 'talk-'+my_talk.id
         });




                                             @lmea #jsday   http://joind.in/3360
Declarative event handling




     var TalkView = Backbone.View.extend({
       // The DOM events specific to a talk.
       events: {
          "click .title"          : "rateIt",
          "click span.edit"       : "edit",
          "keypress input.title"  : "saveOnEnter"
       },
       edit: function() {
         $(this.el).addClass("editing");
         this.$('input.title').focus();
       },
       saveOnEnter: function(e) { },
       rateIt: function(e) { },

     });




                                             @lmea #jsday   http://joind.in/3360
Sub-view element selection




    view.$(selector) // equivalent to $(selector, view.el)
    this.$(".title").text()
    this.$("li input[@name=email]")
    this.$("div #start")




                                            @lmea #jsday     http://joind.in/3360
Binding model events




    var TrackView = Backbone.View.extend({

       initialize: function() {
         _.bindAll(this, 'addOne', 'addAll', 'render');

          this.collection.bind('add',     this.addOne);
          this.collection.bind('refresh', this.addAll);
          this.collection.bind('all',     this.render);

         this.collection.fetch();
       },

    });

    var current_track = new Track(...);
    var track_view = new TrackView({collection: current_track })




                                              @lmea #jsday   http://joind.in/3360
Rendering templates




    <script type="text/template" id="talk-template">
    <div class="talk <%= lightining ? 'ltalk' : '' %>">
        <div class="talk-title"><%= title %></div>
        <span class="talk-speaker"><%= speaker %></span>
        <% for (i=0;i<rating;i++) { %><img src="star.png" /><% } %>
    </div>
    </script>

       render: function() {
         $(this.el).html(this.template(this.model.toJSON()));
         return this;
       },




                                             @lmea #jsday       http://joind.in/3360
Controllers




          intra-page action routing
          evented control flow
          stateful, bookmarkable sub-pages




                                @lmea #jsday   http://joind.in/3360
Controller example




     var ConferenceController = Backbone.Controller.extend({

       routes: {
          "!help":            "help",     // #!help
          "!track/:number":   "search",   // #!track/1
       },

       help: function() {
       },
       search: function(number) {
       }

     });

     new ConferenceController();
     Backbone.history.start();




                                               @lmea #jsday    http://joind.in/3360
Controller routes




     routes: {
       "help/:page":            "help",
       "slides/*path":          "downloadSlides",
       "talk/:track/:talk":     "showTalk",
       "speaker/:name/talks":   "speakerTalks"
       "speaker/:name":         "speaker"
     }

     // Matches #video/10, passing "10"
     this.route("video/:number",
                "video", function(number){ ... });

     // Matches #talk/203/rate/2, passing "203" and "5"
     this.route(/^talk/(.*?)/rate/([1-5])$/,
                "rate", function(id,vote){ ... });




                                               @lmea #jsday   http://joind.in/3360
Backbone.js: demo




          A mobile note taking app
          http://luca.github.com/jsday-demo/




                              @lmea #jsday   http://joind.in/3360
In the end, what does it do?




           JS data models
           Event based
           RESTful (JSON)
           Intra page control flow



                               @lmea #jsday   http://joind.in/3360
And, why should I use it?




           avoids spaghetti code
           cleanly separates concerns
           simple to integrate




                                 @lmea #jsday   http://joind.in/3360
thanks!

http://spazidigitali.com
@lmea

http://www.slideshare.net/lucamea/a-little-backbone-for-your-app



                                       @lmea #jsday      http://joind.in/3360

More Related Content

PDF
Controlling The Cloud With Python
PDF
To Batch Or Not To Batch
PDF
And now you have two problems. Ruby regular expressions for fun and profit by...
PDF
OSCON Google App Engine Codelab - July 2010
PDF
Django Celery - A distributed task queue
PDF
Why Task Queues - ComoRichWeb
PDF
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
ODP
Europython 2011 - Playing tasks with Django & Celery
Controlling The Cloud With Python
To Batch Or Not To Batch
And now you have two problems. Ruby regular expressions for fun and profit by...
OSCON Google App Engine Codelab - July 2010
Django Celery - A distributed task queue
Why Task Queues - ComoRichWeb
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
Europython 2011 - Playing tasks with Django & Celery

What's hot (20)

PDF
Advanced symfony Techniques
PDF
An Introduction to Celery
PDF
Symfony & Javascript. Combining the best of two worlds
PDF
Python RESTful webservices with Python: Flask and Django solutions
PDF
Filling the flask
PPTX
New in php 7
PDF
Practical Celery
PDF
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and more
PDF
The effective use of Django ORM
PDF
Django - 次の一歩 gumiStudy#3
PDF
Django Heresies
PPTX
A Functional Guide to Cat Herding with PHP Generators
PDF
Django
PDF
Introducing Assetic (NYPHP)
PDF
With a Mighty Hammer
PDF
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
PDF
Symfony2 revealed
PPT
Play!ng with scala
PDF
symfony on action - WebTech 207
PDF
Getting Started-with-Laravel
Advanced symfony Techniques
An Introduction to Celery
Symfony & Javascript. Combining the best of two worlds
Python RESTful webservices with Python: Flask and Django solutions
Filling the flask
New in php 7
Practical Celery
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and more
The effective use of Django ORM
Django - 次の一歩 gumiStudy#3
Django Heresies
A Functional Guide to Cat Herding with PHP Generators
Django
Introducing Assetic (NYPHP)
With a Mighty Hammer
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
Symfony2 revealed
Play!ng with scala
symfony on action - WebTech 207
Getting Started-with-Laravel
Ad

Similar to A Little Backbone For Your App (20)

PDF
Backbone.js — Introduction to client-side JavaScript MVC
PPTX
Scala & sling
KEY
[Coscup 2012] JavascriptMVC
PDF
Fun Teaching MongoDB New Tricks
PPTX
Html5 and web technology update
PDF
dojo.Patterns
PDF
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
PPTX
Progressive Enhancment with Rails and React
PDF
WebNet Conference 2012 - Designing complex applications using html5 and knock...
KEY
#NewMeetup Performance
PDF
Great Developers Steal
PPTX
Javascript first-class citizenery
KEY
Summer - The HTML5 Library for Java and Scala
ODP
Exploring Symfony's Code
PPTX
Speed up your developments with Symfony2
PDF
03 form-data
KEY
Express Presentation
PPTX
Design and Development performance considerations
PPTX
4Developers 2018: Pyt(h)on vs słoń: aktualny stan przetwarzania dużych danych...
PDF
Play vs Rails
Backbone.js — Introduction to client-side JavaScript MVC
Scala & sling
[Coscup 2012] JavascriptMVC
Fun Teaching MongoDB New Tricks
Html5 and web technology update
dojo.Patterns
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
Progressive Enhancment with Rails and React
WebNet Conference 2012 - Designing complex applications using html5 and knock...
#NewMeetup Performance
Great Developers Steal
Javascript first-class citizenery
Summer - The HTML5 Library for Java and Scala
Exploring Symfony's Code
Speed up your developments with Symfony2
03 form-data
Express Presentation
Design and Development performance considerations
4Developers 2018: Pyt(h)on vs słoń: aktualny stan przetwarzania dużych danych...
Play vs Rails
Ad

More from Luca Mearelli (9)

PDF
And Now You Have Two Problems
PDF
The anatomy of an infographic
PDF
L'altra meta del web
PDF
WorseSoftware
ZIP
Open Web
PDF
Capistrano2
ZIP
Wikierp
ZIP
Introduzione a Ruby On Rails
PDF
Integrating services with OAuth
And Now You Have Two Problems
The anatomy of an infographic
L'altra meta del web
WorseSoftware
Open Web
Capistrano2
Wikierp
Introduzione a Ruby On Rails
Integrating services with OAuth

Recently uploaded (20)

PDF
Encapsulation_ Review paper, used for researhc scholars
PPTX
Cloud computing and distributed systems.
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Modernizing your data center with Dell and AMD
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PPT
Teaching material agriculture food technology
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Empathic Computing: Creating Shared Understanding
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PPTX
Big Data Technologies - Introduction.pptx
PDF
Spectral efficient network and resource selection model in 5G networks
Encapsulation_ Review paper, used for researhc scholars
Cloud computing and distributed systems.
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
NewMind AI Weekly Chronicles - August'25 Week I
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Mobile App Security Testing_ A Comprehensive Guide.pdf
Modernizing your data center with Dell and AMD
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Teaching material agriculture food technology
Diabetes mellitus diagnosis method based random forest with bat algorithm
Empathic Computing: Creating Shared Understanding
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Dropbox Q2 2025 Financial Results & Investor Presentation
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
20250228 LYD VKU AI Blended-Learning.pptx
Understanding_Digital_Forensics_Presentation.pptx
Digital-Transformation-Roadmap-for-Companies.pptx
Big Data Technologies - Introduction.pptx
Spectral efficient network and resource selection model in 5G networks

A Little Backbone For Your App

  • 1. A Little For Your App Luca Mearelli
  • 2. var Luca = (function(){ var me = {}; me.is = 'craftsman'; me.twitter = '@lmea'; me.did = ['http://miojob.repubblica.it', 'http://kiaraservice.com', '...']; me.uses = function(tool){ _.indexOf(['ruby', 'rails', 'javascript'], tool)>=0; } me.used = function(tool){ _.indexOf(['c++', 'python', 'java'], tool)>=0; } return me; })() @lmea #jsday http://joind.in/3360
  • 3. http://github.com/documentcloud/backbone/ @lmea #jsday http://joind.in/3360
  • 4. A quick poll Using DOM libraries? Using (end-to-end) frameworks? Know or used backbone.js? @lmea #jsday http://joind.in/3360
  • 5. Backbone.js: what is it? A lightweight collection of tools giving enough structure to help building apps in the browser without getting in the way @lmea #jsday http://joind.in/3360
  • 6. Backbone.js: what is it for? Data heavy pages Frontends to (JSON) web services CRUD-kind web apps @lmea #jsday http://joind.in/3360
  • 7. Backbone.js: Model-View-Controller model view controller @lmea #jsday http://joind.in/3360
  • 8. Elements of backbone Model Collection View Controller @lmea #jsday http://joind.in/3360
  • 9. Elements of backbone (2) Event Sync History @lmea #jsday http://joind.in/3360
  • 10. Model & Collection Representing the data Building the business logic Handling persistence @lmea #jsday http://joind.in/3360
  • 11. The simplest model var Talk = Backbone.Model.extend({}) @lmea #jsday http://joind.in/3360
  • 12. Initializing & setting defaults var Talk = Backbone.Model.extend({ // Default attributes for Talk defaults: { title: "a talk", speaker: "me", lenght: 60 }, intialize: function(){ if (this.length>10) { this.set({"lightining": false}); } }, }) @lmea #jsday http://joind.in/3360
  • 13. Assorted CRUD methods var my_talk = new Talk({title: "A Little Backbone"}); my_talk.get("title"); my_talk.set({"speaker":"Luca Mearelli"}); if(my_talk.has("video")){ //... }; my_talk.unset("speaker") my_talk.id my_talk.cid @lmea #jsday http://joind.in/3360
  • 14. Custom functions var Talk = Backbone.Model.extend({ full_info: function(){ return this.get("title")+" by:"+this.get("speaker"); }, rate: function(stars){ if(_.isUndefined(this.get("rating"))){ this.save({rating: stars}); } }, }) @lmea #jsday http://joind.in/3360
  • 15. Validating models var Talk = Backbone.Model.extend({ validate: function(attrs) { if (_.isEmpty(attrs.title)) { return "The title should be defined"; } if (attrs.lenght>60) { return "The maximum lenght is 60 minutes"; } } }); my_talk.bind("error", function(model, error) { alert(model.full_info() + " " + error); }); my_talk.set({"lenght":120}); @lmea #jsday http://joind.in/3360
  • 16. Saving models // delegates to Backbone.sync my_talk.save(); // if my_talk.isNew() -> ‘create’ (HTTP “POST”) my_talk.save({title:"ahah"}) // otherwise ‘update’ (HTTP “PUT”) my_talk.save({...}, { success: function(model, resp, xhr){...}, error: function(model, errormsg){...} }); my_talk.url(); // /[collection.url]/[id] or /[urlRoot]/[id] Talk.urlRoot = '/talks'; @lmea #jsday http://joind.in/3360
  • 17. Backbone.sync Backbone.sync = function(method, model, options) { switch (method) { case "read": ... break; // read ! GET /collection[/id] case "create": ... break; // create ! POST /collection case "update": ... break; // update ! PUT /collection/id case "delete": ... break; // delete ! DELETE /collection/id } }; // to emulate put & delete with post + parameter Backbone.emulateHTTP = true; @lmea #jsday http://joind.in/3360
  • 18. Models collection var Track = Backbone.Collection.extend({ model: Talk }); var track_talks = new Track([talk1, talk2, talk3]); track_talks.get(talk2.id); // gets talk2 track_talks.at(0); // gets talk1 track_talks.lenght; // is 3 @lmea #jsday http://joind.in/3360
  • 19. Collection: adding and removing models track_talks.add( {title:"JavaScript Survival Guide",speaker:"Giordano Scalzo " } ); track_talks.add([ {title: "Faster Web Sites 2.0", speaker: "Steve Souders" }, {title: "HTML5, the current status", speaker:"Patrick H. Lauke"} ]); track_talks.remove(talk1); track_talks.remove([talk2, talk3]); track_talks.refresh([ {title:"Javascript the New Parts",speaker: "Federico Galassi" } ]); @lmea #jsday http://joind.in/3360
  • 20. Fetching a collection from the server var Track = Backbone.Collection.extend({ url: function(){ return "/tracks/"+this.get("number"); }, // or simply url: "/talks" }); var track_talks = new Track({number: 1}) track_talks.fetch(); // calls model.parse(response) @lmea #jsday http://joind.in/3360
  • 21. Custom sorted collections track_talks.comparator = function(talk) { return talk.get("time"); } track_talks.add(new Talk({time: 17, title: "A Little Backbone"})); track_talks.add(new Talk({time: 9, title: "Faster Web Sites 2.0"})); track_talks.add(new Talk({time: 10, title: "JavaScript Survival Guide"})); alert(track_talks.pluck('title')); track_talks.sort(); @lmea #jsday http://joind.in/3360
  • 22. Underscore.js goodies var Track = Backbone.Collection.extend({ future: function() { return this.filter(function(talk){ return todo.get('time')>(new Date()).getHours(); }); }, next: function() { return this.first.apply(this, this.future()); } // forEach (each), map, reduce (foldl, inject), // reduceRight (foldr), find (detect), filter (select), // reject, every (all), some (any), include, invoke, max, // min, sortBy, sortedIndex, toArray, size, first, rest, // last, without, indexOf, lastIndexOf, isEmpty, chain }); @lmea #jsday http://joind.in/3360
  • 23. Views is a small chunk of the page has declarative event handling acts like a view controller @lmea #jsday http://joind.in/3360
  • 24. A basic view // The DOM element for a talk var TalkView = Backbone.View.extend({ //... is a div tag. tagName: "div", className: "a-talk-row", render: function() { $(this.el).html(this.model.full_info()); return this; }, }); v = new TalkView({ model:my_talk, id: 'talk-'+my_talk.id }); @lmea #jsday http://joind.in/3360
  • 25. Declarative event handling var TalkView = Backbone.View.extend({ // The DOM events specific to a talk. events: { "click .title" : "rateIt", "click span.edit" : "edit", "keypress input.title" : "saveOnEnter" }, edit: function() { $(this.el).addClass("editing"); this.$('input.title').focus(); }, saveOnEnter: function(e) { }, rateIt: function(e) { }, }); @lmea #jsday http://joind.in/3360
  • 26. Sub-view element selection view.$(selector) // equivalent to $(selector, view.el) this.$(".title").text() this.$("li input[@name=email]") this.$("div #start") @lmea #jsday http://joind.in/3360
  • 27. Binding model events var TrackView = Backbone.View.extend({ initialize: function() { _.bindAll(this, 'addOne', 'addAll', 'render'); this.collection.bind('add', this.addOne); this.collection.bind('refresh', this.addAll); this.collection.bind('all', this.render); this.collection.fetch(); }, }); var current_track = new Track(...); var track_view = new TrackView({collection: current_track }) @lmea #jsday http://joind.in/3360
  • 28. Rendering templates <script type="text/template" id="talk-template"> <div class="talk <%= lightining ? 'ltalk' : '' %>"> <div class="talk-title"><%= title %></div> <span class="talk-speaker"><%= speaker %></span> <% for (i=0;i<rating;i++) { %><img src="star.png" /><% } %> </div> </script> render: function() { $(this.el).html(this.template(this.model.toJSON())); return this; }, @lmea #jsday http://joind.in/3360
  • 29. Controllers intra-page action routing evented control flow stateful, bookmarkable sub-pages @lmea #jsday http://joind.in/3360
  • 30. Controller example var ConferenceController = Backbone.Controller.extend({ routes: { "!help": "help", // #!help "!track/:number": "search", // #!track/1 }, help: function() { }, search: function(number) { } }); new ConferenceController(); Backbone.history.start(); @lmea #jsday http://joind.in/3360
  • 31. Controller routes routes: { "help/:page": "help", "slides/*path": "downloadSlides", "talk/:track/:talk": "showTalk", "speaker/:name/talks": "speakerTalks" "speaker/:name": "speaker" } // Matches #video/10, passing "10" this.route("video/:number", "video", function(number){ ... }); // Matches #talk/203/rate/2, passing "203" and "5" this.route(/^talk/(.*?)/rate/([1-5])$/, "rate", function(id,vote){ ... }); @lmea #jsday http://joind.in/3360
  • 32. Backbone.js: demo A mobile note taking app http://luca.github.com/jsday-demo/ @lmea #jsday http://joind.in/3360
  • 33. In the end, what does it do? JS data models Event based RESTful (JSON) Intra page control flow @lmea #jsday http://joind.in/3360
  • 34. And, why should I use it? avoids spaghetti code cleanly separates concerns simple to integrate @lmea #jsday http://joind.in/3360