SlideShare a Scribd company logo
1 of 35
Download to read offline
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

What's hot

Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
Ignacio Martín
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)
Kris Wallsmith
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
patter
 

What's hot (20)

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

Similar to A Little Backbone For Your App

09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
Igor Bronovskyy
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup Performance
Justin Cataldo
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2
Hugo Hamon
 
03 form-data
03 form-data03 form-data
03 form-data
snopteck
 
Design and Development performance considerations
Design and Development performance considerationsDesign and Development performance considerations
Design and Development performance considerations
Elaine Van Bergen
 

Similar to A Little Backbone For Your App (20)

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

More from Luca Mearelli

Integrating services with OAuth
Integrating services with OAuthIntegrating services with OAuth
Integrating services with OAuth
Luca Mearelli
 

More from Luca Mearelli (9)

And Now You Have Two Problems
And Now You Have Two ProblemsAnd Now You Have Two Problems
And Now You Have Two Problems
 
The anatomy of an infographic
The anatomy of an infographicThe anatomy of an infographic
The anatomy of an infographic
 
L'altra meta del web
L'altra meta del webL'altra meta del web
L'altra meta del web
 
WorseSoftware
WorseSoftwareWorseSoftware
WorseSoftware
 
Open Web
Open WebOpen Web
Open Web
 
Capistrano2
Capistrano2Capistrano2
Capistrano2
 
Wikierp
WikierpWikierp
Wikierp
 
Introduzione a Ruby On Rails
Introduzione a Ruby On RailsIntroduzione a Ruby On Rails
Introduzione a Ruby On Rails
 
Integrating services with OAuth
Integrating services with OAuthIntegrating services with OAuth
Integrating services with OAuth
 

Recently uploaded

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Recently uploaded (20)

Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 

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