Build spaghetti-proof web apps
JAVASCRIPT ?
JAVASCRIPT ?
JAVASCRIPT ?
LA PHILOSOPHIE
LA PHILOSOPHIE
• Application web monopage
LA PHILOSOPHIE
• Application web monopage
• Architecture MV(C?)
LA PHILOSOPHIE
• Application web monopage
• Architecture MV(C?)
• Framework léger
LA PHILOSOPHIE
• Application web monopage
• Architecture MV(C?)
• Framework léger
• Agnostique
LA PHILOSOPHIE
• Application web monopage
• Architecture MV(C?)
• Framework léger
• Agnostique
• Communication RESTful
LA PHILOSOPHIE
• Application web monopage
• Architecture MV(C?)
• Framework léger
• Agnostique
• Communication RESTful
• Dépendance Underscore.js et jQuery
LA WEB-APP CLASSIQUE

Serveur                         Client
                        HTML
• Logique business             • Requête
• Gestion des données          • Parsing HTML et
• Templating                   affichage
• i18n
LA WEB-APP CLASSIQUE

Serveur                         Client
                        HTML
• Logique business             • Requête
• Gestion des données          • Parsing HTML et
• Templating                   affichage
• i18n

   x nClients
LA WEB-APP CLASSIQUE

Serveur                         Client
                        HTML
• Logique business             • Requête
• Gestion des données          • Parsing HTML et
• Templating                   affichage
• i18n

   x nClients
LA WEB-APP CLASSIQUE

Serveur                         Client
                        HTML
• Logique business             • Requête
• Gestion des données          • Parsing HTML et
• Templating                   affichage
• i18n

   x nClients
LA WEB-APP CLASSIQUE

Serveur                          Client
                        HTML
• Logique business              • Requête
• Gestion des données           • Parsing HTML et
• Templating                    affichage
• i18n

  x nClients
  + Templating complet à chaque changement de page
LA WEB-APP CLASSIQUE

Serveur                          Client
                        HTML
• Logique business              • Requête
• Gestion des données           • Parsing HTML et
• Templating                    affichage
• i18n

  x nClients
  + Templating complet à chaque changement de page
LA WEB-APP BACKBONE

Serveur                         Client
                        JSON   • Requête
                               • Templating
• Logique business             • i18n
• Gestion des données          • Récupération des
                               données
LA WEB-APP BACKBONE

Serveur                         Client
                        JSON   • Requête
                               • Templating
• Logique business             • i18n
• Gestion des données          • Récupération des
                               données


Requêtes légères
LA WEB-APP BACKBONE

Serveur                         Client
                        JSON   • Requête
                               • Templating
• Logique business             • i18n
• Gestion des données          • Récupération des
                               données


Requêtes légères               Travaille pour nous
L’EXEMPLE
LES MODÈLES
# Création de la classe d'un Tweet
Tweet = Backbone.Model.extend
    urlRoot: "/api/tweets"
    validate: (attributes)->
        if attributes.author == "" then return "Invalid author"
        if attributes.text == "" or attributes.text.length > 140 then return 
"Invalid tweet"
 
# Instanciation d'un nouveau Tweet
aTweet = new Tweet(
    author: "Hugoch"
    text: "Hey, I'm presenting #Backbonejs at #NWXTech5 conference."
)
 

 




 
LES MODÈLES
# Création de la classe d'un Tweet
Tweet = Backbone.Model.extend
    urlRoot: "/api/tweets"
    validate: (attributes)->
        if attributes.author == "" then return "Invalid author"
        if attributes.text == "" or attributes.text.length > 140 then return 
"Invalid tweet"
 
# Instanciation d'un nouveau Tweet
aTweet = new Tweet(
    author: "Hugoch"
    text: "Hey, I'm presenting #Backbonejs at #NWXTech5 conference."
)
 
aTweet.save()
 
                                          POST /api/tweets

 
LES MODÈLES
# Création de la classe d'un Tweet
Tweet = Backbone.Model.extend
    urlRoot: "/api/tweets"
    validate: (attributes)->
        if attributes.author == "" then return "Invalid author"
        if attributes.text == "" or attributes.text.length > 140 then return 
"Invalid tweet"
 
# Instanciation d'un nouveau Tweet
aTweet = new Tweet(
    author: "Hugoch"
    text: "Hey, I'm presenting #Backbonejs at #NWXTech5 conference."
)
 
aTweet.save()
 
                                          POST /api/tweets
aTweet.save(
    author: "Chuck Norris"                PUT /api/tweets/42
)
 
LES MODÈLES
# Création de la classe d'un Tweet
Tweet = Backbone.Model.extend
    urlRoot: "/api/tweets"
    validate: (attributes)->
        if attributes.author == "" then return "Invalid author"
        if attributes.text == "" or attributes.text.length > 140 then return 
"Invalid tweet"
 
# Instanciation d'un nouveau Tweet
aTweet = new Tweet(
    author: "Hugoch"
    text: "Hey, I'm presenting #Backbonejs at #NWXTech5 conference."
)
 
aTweet.save()
 
                                          POST /api/tweets
aTweet.save(
    author: "Chuck Norris"                PUT /api/tweets/42
)
 
aTweet.destroy()                         DELETE /api/tweets/42
LES COLLECTIONS
                                           [
# Création d'une collection de tweets          {
Tweets = Backbone.Collection.extend                "id": 544102,
    model: Tweet                                   "author": "N_W_X",
    url: "/api/tweets"                             "text": "Conférence #nwxtech5 du 24 
                                                      janvier, avec @GrieuL @nautilebl
# Instanciation de la collection                      eu @romainlouvet @zigazou @hugoc
someTweets = new Tweets()                             h et @moebius_eye : amiando.com/
                                                      nwxtech5"
# Récupération des Tweets sur le serveur       },
someTweets.fetch()                             {
                                                   "id": 24454,
                                                   "author": "N_W_X",
                                                   "text": "Conférence dédiée aux tech
                                                      nos web #nwxtech5 à Rouen le 24 
                                                      janvier :  amiando.com/nwxtech5"
                                               }
                                           ]
LES VUES
• Une vue = un élément du DOM                 # Création d'une vue de tweet
                                              TweetView = Backbone.View.extend
• Une vue représente un modèle                    tagName: "li"
                                                  className: "tweet"
• Possibilité de mettre à jour une                render: ()->
                                                      tpl = _.template("""<h2><%-author%></h2>
                                                      <p><%-text%></p>""")
 portion de page                                      @$el.append(tpl(@model.toJSON()))
                                                      return @




  # Instanciation de la collection
  someTweets = new Tweets()
   
  # Affichage des tweets lorsqu'ils sont ajoutés à ma collection
  someTweets.on("add",(tweet)->
      view = new TweetView(
          model: tweet
      )
      $("#tweet-list").append(view.render().el)
  )
LES ROUTEURS
                                       # On crée la classe de routeur

• Gèrent la navigation au sein de la   TweetApp = Backbone.Router.extend
                                           routes:
                                               "last/:num":    "showLast"
 web-app avec des URL                          "*path":        "home"
                                        
 transparentes (History API des            showLast: (num)->
                                               # Récupération des nums
                                               derniers Tweets sur le serveur
 navigateurs)                                  someTweets.fetch(
                                                   update: true
• Permettent aux utilisateurs de                   data:
                                                       limit: num
                                               )
 bookmarker des vues de                 
                                           home: ()->
 l’application                                 someTweets.fetch(
                                                   update: true
                                               )
                                       # Instanciation du routeur
                                       app = new TweetApp()

                                       # Démarrage de l'app
                                       Backbone.history.start({pushState: true})
L’APPLICATION
<html>
<head>
    <script src="jquery.js"></script>
    <script src="underscore.js"></script>
    <script src="backbone.js"></script>
    <script src="examples.js"></script>
    <link href="stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/
css" />
</head>
<body>
    <div id="container">
        <h1>Ecrire un tweet</h1>
        <div class="form-row">
            <label for="new-tweet">Votre message</label>
        </div>
        <div class="form-row">
            <textarea id="new-tweet"></textarea>
        </div>
        <div class="form-row right">
            <button id="send-tweet">Envoyer</button>
        </div>
 
        <h1>Derniers tweets</h1>
            <ul id="tweet-list">
            </ul>                                    Insertion des vues de tweets
    </div>
</body>
</html>
L’APPLICATION
                                                                  # On écoute le clic sur le bouton de création de tweet
# Création de la classe d'un Tweet
                                                                  $(()->
Tweet = Backbone.Model.extend
                                                                      $("#send-tweet").click(()->
    urlRoot: "/api/tweets"
                                                                          tweet = new Tweet()
    validate: (attributes)->
                                                                          if tweet.save(
        if attributes.author == "" then return "Invalid author"
                                                                              author: $("#author").val()
        if attributes.text == "" or attributes.text.length > 14
                                                                              text: $("#new-tweet").val()
0 then return "Invalid tweet"
                                                                          )
  
                                                                              someTweets.add(tweet)
# Création d'une collection de tweets
                                                                              $("#new-tweet").val("").focus()
Tweets = Backbone.Collection.extend
                                                                      )
    model: Tweet
                                                                  )
    url: "/api/tweets"
                                                                   
 
                                                                  # On crée la classe de routeur
# Instanciation de la collection
                                                                  TweetApp = Backbone.Router.extend
someTweets = new Tweets()
                                                                      routes:
 
                                                                          "last/:num":    "showLast"
# Affichage des tweets lorsqu'ils sont ajoutés à ma collection
                                                                          "*path":        "home"
someTweets.on("add",(tweet)->
                                                                   
    view = new TweetView(
                                                                      showLast: (num)->
        model: tweet
                                                                          # Récupération des Tweets sur le serveur
    )
                                                                          someTweets.fetch(
    $("#tweet-list").prepend(view.render().el)
                                                                              update: true
)
                                                                              data:
 
                                                                                  limit: num
# Création d'une vue de tweet
                                                                          )
TweetView = Backbone.View.extend
                                                                   
    tagName: "li"
                                                                      home: ()->
    className: "tweet"
                                                                          someTweets.fetch(
    render: ()->
                                                                              update: true
        tpl = _.template("""<h2><%-author%></h2>
                                                                          )
        <p><%-text%></p>""")
        @$el.append(tpl(@model.toJSON()))
                                                                  # Instanciation du routeur
        return @
                                                                  app = new TweetApp()
 
                                                                  # Démarrage de l'app
                                                                  Backbone.history.start({pushState: true})
EXEMPLE
nwxtech.herokuapp.com
CONVAINCU ?
• 117 lignes de code (serveur + javascript)
• Temps réel
• 1 chargement des ressources (serveur statique),
  puis 300 octets par tweet
• Plugins : Backbone.Relational, LocalStorage
Utilisé par :
SIGINT
Plus d’infos
 • Backbone.js ➔ backbonejs.org
 • GitHub      ➔ github.com/documentcloud/backbone
 • Exemple ➔ github.com/Plixee/backbone-nwx-example
Contact
                 hugo@plixee.com
                      @hugoch

                                     www.plixee.com

Conférence #nwxtech5 : Introduction à Backbone.js par Hugo Larcher