I. Préparation

Avant de commencer ce tutoriel, vous aurez besoin de ce qui suit :

Pour consulter la source, exécutez les commandes suivantes (ou utilisez un outil approprié pour Git GUI) :

 
Sélectionnez
git clone git@github.com:alexyoung/dailyjs-backbone-tutorial.git
cd dailyjs-backbone-tutorial
git reset --hard 82fe08e

II. Liste CRUD

Les dernières parties de cette série de tutoriels ont démontré comment communiquer avec l'API Google Tasks et comment s'authentifier avec OAuth. À ce stade, vous devriez être en mesure de vous connecter et de consulter la liste des listes de tâches.

Comme nous l'avons vu, Backbone.js est basé sur les API RESTful qui parlent en termes de CRUD (create/créer, read/lire, update/mettre à jour et delete/supprimer). Dans la partie 4, j'ai expliqué comment écrire une méthode personnalisée de Backbone.sync qui peut communiquer avec les API Google. Mais jusqu'ici nous avons seulement mis en œuvre la fonctionnalité de lecture pour extraire les listes de tâches à l'aide de gapi.client.tasks.

Maintenant, il faut vraiment mettre en œuvre l'ensemble des opérations CRUD afin que les utilisateurs puissent gérer des listes. La partie 4 a montré comment lier l'API Google à Backbone pour synchroniser les opérations :

 
Sélectionnez
API Google Tasks | Méthode Backbone.sync | Description
------------------------------------------------------
    insert       |         create        | Créer une nouvelle tâche.
    update       |         update        | Mettre à jour une tâche existante.
    delete       |         delete        | Supprimer une tâche.
     list        |          read         | Obtenir une liste de tâches.

Dans cette partie nous allons ajouter le support pour la création de listes. Mais comme vous le verrez, les principes sont très semblables à la mise en œuvre de la lecture.

III. Création de listes

Afin de créer des listes, plusieurs nouveaux éléments sont nécessaires :

  1. Des boutons appropriés ;
  2. Un template de formulaire ;
  3. Ajouter et modifier des vues ;
  4. Le code du contrôleur.

Dans Backbone.js les modèles et les collections émettent des événements. Nous avons déjà créé le code pour gérer des affichages d'éléments de listes, alors tout ce que nous devons faire est de s'accrocher à l'événement qui se déclenche lorsqu'un nouveau modèle est créé et de l'ajouter à la collection de listes.

Maîtriser et exploiter les événements de cette manière est une astuce pour écrire du code de Backbone.js gérable.

IV. Backbone.sync

Jusqu'ici, Backbone.sync peut lire uniquement les listes de l'API Google. Pour le rendre capable de créer des éléments, nous aurons besoin d'un peu de code supplémentaire. Il s'appuiera sur ce que nous avons déjà écrit, donc il sera court et simple.

Ouvrez le fichier app/js/gapi.js et changez Backbone.sync pour appeler gapiRequest lorsque l'opération de création est invoquée :

 
Sélectionnez
Backbone.sync = function(method, model, options) {
  var requestContent = {};
  options || (options = {});

  switch (method) {
    case 'create':
      requestContent['resource'] = model.toJSON();
      request = gapi.client.tasks[model.url].insert(requestContent);
      Backbone.gapiRequest(request, method, model, options);
    break;

Cela ressemble beaucoup au code de la lecture. Il y a encore une chose qu'il faut faire dans ce fichier. C'est modifier Backbone.gapiRequest pour s'occuper des ressources uniques. J'ai mis le code complet pour la méthode ci-dessous parce qu'elle est tout aussi courte avec les modifications pour ce tutoriel :

 
Sélectionnez
Backbone.gapiRequest = function(request, method, model, options) {
  var result;
  request.execute(function(res) {
    if (res.error) {
      if (options.error) options.error(res);
    } else if (options.success) {
      if (res.items) {
        result = res.items;
      } else {
        result = res;
      }
      options.success(result, true, request);
    }
  });
};

Ceci vérifie si un tableau d'éléments ou tout simplement un objet unique a été retourné par l'API Google. Il y a cependant une importante leçon ici : Backbone.sync est pris en tenailles entre les autres codes de Bakcbone et est capable de fournir du code Backbone avec des propriétés qui serviront à définir des attributs de modèle par la suite. Ce code ne semble pas faire cela, mais le callback success recevra le résultat. Lequel aura une propriété id lors de la création des modèles. Backbone voit cette propriété id et l'utilise pour positionner l'attribut id du modèle automatiquement !

Many Bothans died to bring us this information.

V. Template Junk

Ouvrez le fichier app/js/templates/app.html et mettez à jour la div signed-in-container pour qu'elle contienne une liste et un autre conteneur :

 
Sélectionnez
<ul class="nav nav-tabs" id="top-nav">
  <li class="buttons">
    <div class="btn-group">
      <a href="#" class="btn" id="add-list-button"><i class="icon-plus">Ajouter la liste</i></a>
      <a href="#" class="btn" id="edit-list-button"><i class="icon-cog">Modifier la liste</i></a>
      <a href="#" class="btn delete-list" id="delete-list-button"><i class="icon-trash">Supprimer la liste</i></a>
    </div>
  </li>
</ul>
<div id="content-container">
  <div id="list-editor"></div>
  <div id="tasks-container"></div>
</div>

C'est le bouton « Ajouter la liste » que vous serez en mesure d'utiliser à la fin de ce tutoriel, et il a aussi une div qui va contenir le formulaire d'ajout/de modification de la liste.

Maintenant, ouvrez app/js/templates/lists/form.html et collez ceci dedans :

 
Sélectionnez
<fieldset>
  <legend>
    <span class="form-title">Modification de la liste</span>
    <a href="#" class="pull-right delete-list btn"><i class="icon-trash"></i></a>
  </legend>
  <div class="control-group">
    <label class="control-label" for="list_title">Titre</label>
    <div class="controls">
      <input type="text" class="input-xlarge" name="title" id="list_title" value="" placeholder="Le titre de la liste">
    </div>
  </div>
</fieldset>
<div class="form-actions">
  <button type="submit" class="btn btn-primary">Sauvegarder les changements</button>
  <button class="cancel btn">Fermer</button>
</div>

C'est le corps d'un formulaire qui sera utilisé pour ajouter ou modifier des listes. Il utilise les fonctions d'interpolation variable que nous avons déjà vues dans cette série de tutoriels.

VI. Ajout et modification des vues

Je ne vais pas couvrir l'ajout de listes dans ce tutoriel, nous reviendrons sur les autres fonctionnalités plus tard (principalement parce que j'ai écrit ceci pendant trois heures et que j'ai du travail à faire, j'ai besoin de payer les factures). Paiement de factures mis de côté, quelle est la différence entre une vue d'ajout et une vue de modification ? Le modèle form.html peut être réutilisé par les deux alors pourquoi ne pas créer seulement une vue de modification et hériter d'elle pour faire la vue d'ajout ?

Ouvrez le fichier app/js/views/lists/edit.js et ajoutez cette nouvelle vue :

 
Sélectionnez
define(['text!templates/lists/form.html'], function(template) {
  var EditListView = Backbone.View.extend({
    tagName: 'form',
    className: 'form-horizontal well edit-list',
    template : _.template(template),

    events: {
      'submit': 'submit'
    , 'click .cancel' : 'cancel'
    },

    initialize: function() {
      this.model.on('change', this.render, this);
    },

    render: function() {
      var $el = $(this.el);
      $el.html(this.template(this.model.toJSON()));

      if (!this.model.get('id')) {
        this.$el.find('legend').html('Ajouter une liste');
      }

      return this;
    },

    submit: function() {
      var self = this
        , title = this.$el.find('input[name="title"]').val()
        ;

      this.model.save({ title: title }, {
        success: function() {
          self.remove();
        }
      });

      return false;
    },

    cancel : function() {
      this.$el.hide();
      return false;
    }
  });

  return EditListView;
});

Dans cette classe, j'ai déclaré les événements pour la soumission et la fermeture du formulaire et les ai liés aux méthodes appropriées. J'ai également lié l'événement change de la vue à render donc les modifications apportées au modèle s'afficheront automatiquement. Cela sera important par la suite.

Notez que dans render la legend sera modifiée lorsque le modèle n'a pas encore d'identifiant. En d'autres termes, lorsque le modèle est nouveau et n'a pas été enregistré, on montre un autre titre et on cache le bouton de suppression.

Maintenant, comparez ce fichier au fichier app/js/views/lists/add.js :

 
Sélectionnez
define([
'models/tasklist'
, 'views/lists/edit'
],

function(TaskList, EditListView) {
var AddListView = EditListView.extend({
  submit: function() {
    var self = this
      , title = this.$el.find('input[name="title"]').val()
      ;

    this.model.save({ title: title }, { success: function(model) {
      // Ajouter le modèle de mise à jour à la collection
      bTask.collections.lists.add(model);
      self.remove();
    }});

    return false;
  }
});

return AddListView;
});

Ce fichier utilise RequireJS pour charger EditListView dont il hérite. La méthode submit est remplacée parce que la création de listes est légèrement différente pour la mise à jour. Lorsque les listes sont créées, on reçoit un modèle de mise à jour depuis le serveur dans le callback success, ce qui peut être ajouté à la collection de listes globales. La vue se supprime elle-même par la suite.

VII. Le bouton d'ajout de liste

Un lien permettant d'ajouter des listes a été placé précédemment sur le modèle principal app.html. Ouvrez app/js/views/app.js et ajoutez une nouvelle méthode appelée addList :

 
Sélectionnez
addList: function() {
  var list = new bTask.collections.lists.model({ title: '' })
    , form = new AddListView({ model: list })
    , self = this
    ;

  this.$el.find('#list-editor').html(form.render().el);
  form.$el.find('input:first').focus();

  return false;
}

Cela affiche le template AddListView et met le focus sur le champ titre. Vous devrez également modifier la partie supérieure du fichier pour charger AddListView :

 
Sélectionnez
define([
  'text!templates/app.html'
, 'views/lists/add'
],

function(template, AddListView) {

Enfin, ajoutez les liaisons d'événements quelque part dans AppView :

 
Sélectionnez
events: {
  'click #add-list-button': 'addList'
},

VIII. Résumé

Image non disponible

Si vous exécutez le serveur Node et visitez la page http://localhost:8080, vous êtes maintenant en mesure d'ajouter des listes. Le projet ne semble pas encore particulièrement génial mais je vais bientôt changer cela.

Le code source de ce tutoriel se trouve ici : alexyoung / dailyjs-backbone-tutorial en version 465523f.

IX. Remerciements

Cet article a été publié avec l'aimable autorisation de Alex Young. L'article original peut être lu sur le site DailyJSDailyJS : Backbone.js Tutorial: Creating ListsBackbone.js Tutorial: Creating Lists.
Je remercie également ClaudeLELOUP pour sa relecture attentive et assidue.