Présentation de Backbone.js

Arthur WEBER

Cet article a été publié avec l'aimable autorisation de Ippon technologies et d'Arthur WEBER.

Commentez

- Titre : Présentation de Backbone.js

- Auteur : Arthur WEBER

- Parution : 12 septembre 2013

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2013 Arthur WEBER. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Présentation

- I-A. Introduction

- I-B. Ses dépendances

- II. Les composants

- III. Les données

- III-A. Backbone.Model

- III-B. Backbone.Collection

- III-C. Backbone.Sync

- IV. La vue

- IV-A. Backbone.View

- IV-B. Les événements

- V. Exemple complet

- VI. Pour aller plus loin

- VI-A. Gestion des routes

- VI-B. Asynchronous Module Definition API

- VI-C. Plugins

- VII. Conclusion

- VIII. Remerciements

I - Présentation

I-A - Introduction

Backbone.js est un framework JavaScript basé sur la librairie Underscore.js. Il permet de structurer une application Web, non plus comme une suite d'instructions jQuery, mais comme un assemblage de vues autonomes les unes des autres.
Son but est de poser des bases fortes pour développer des applications riches, sans pour autant imposer une structure applicative.

Il se veut non-contraignant par rapport à ses rivaux, ce qui lui coûte d'être présenté souvent comme moins complet. Son point fort est d'être facilement utilisable avec d'autres bibliothèques ou frameworks.

I-B - Ses dépendances

Backbone.js est basé sur la librairie Underscore.js. Cette dernière propose des fonctionnalités de manipulation d'objets, de collections et de tableaux assez poussées. Comme toute bibliothèque populaire, elle se veut cross-browser et par héritage, Backbone.js l'est aussi.

Pour tout ce qui est manipulation DOM, plutôt que réinventer la roue, l'équipe en charge de Backbone.js a décidé de sous-traiter cette tâche à jQuery. Il est possible de remplacer jQuery, par exemple avec Zepto, du moment qu'elle respecte l'API jQuery-compatible.

II - Les composants

Backbone.js fournit des composants logiciels pouvant être utilisés librement, que ce soit avec les autres composants Backbone.js ou avec une autre bibliothèque. Les trois plus importants sont le Model, la Collection et la View.

On parlera également de deux composants moins importants mais qui fournissent des fonctionnalités très intéressantes : Router et Sync.

L'utilisation de chaque composant se fait par extension de la classe. Lors de l'extension, il est possible de réimplémenter les méthodes ou de redéfinir les attributs et ainsi paramétrer l'objet pour que son comportement corresponde à nos attentes. La documentation est très bien fournie sur ce point qui se trouve être, à mon sens, un des points forts de Backbone.js.

var ExtendClass = Backbone.Model.extend({
initialize: function() { ... }
});

III - Les données

III-A - Backbone.Model

La classe Backbone.Model est utilisée pour gérer du contenu sous la forme d'un objet JavaScript en l'encapsulant et en proposant des méthodes de type accesseurs.

var Article = Backbone.Model.extend({});
var article = new Article({
title: 'New Article'
});

article.get('title'); // New Article
article.set('title', 'New title');
article.get('title'); // New title

Testez ce code en ligne sur jsfiddle.

III-B - Backbone.Collection

La classe Backbone.Collection permet de manipuler des collections de Model. On y retrouve les méthodes habituelles : push, pop, shift, unshift, add, remove, get, sort ou encore length. On retrouve également les fonctions provenant de Underscore.js.

var Article = Backbone.Model.extend({});
var Articles = Backbone.Collection.extend({
model : Article
});

var articles = new Articles([{
title: 'Article 1'
},{
title: 'Article 2'
},{
title: 'Article 3'
}]);

articles.push(articles.shift());
articles.models = articles.shuffle();

Testez ce code en ligne sur jsfiddle.

III-C - Backbone.Sync

Concrètement, jusque-là, nous avons vu comment manipuler des données. Mais pourquoi s'embêter avec alors que nous pourrions le faire plus simplement ? C'est Sync qui va vous apporter la réponse.

Sync est le composant permettant de synchroniser les objets à travers une API du type « RESTful JSON ». Pour cela, il suffit de lier les objets Model et Collection à une ressource grâce à l'attribut url.

var urlModel = 'http://ippon.fr/articles/1';
var urlCollection = 'http://ippon.fr/articles';
var Article = Backbone.Model.extend({
url: urlModel;
});

var Articles = Backbone.Collection.extend({
model: Article,
url: urlCollection
});

Testez ce code en ligne sur jsfiddle.

IV - La vue

Comme je l'ai signalé au début de l'article, Backbone.js a pour but de poser les bases du développement MVC en JavaScript. C'est pourquoi, pour toutes les manipulations DOM, on retrouve le plugin jQuery qui est de loin le mieux armé pour ces opérations.

IV-A - Backbone.View

Chaque objet Backbone.View est lié à un nœud DOM (el) et pourra le générer à nouveau, à n'importe quel moment. Le but est alors de découper le document en une multitude de vues que l'on pourra régénérer à souhait et individuellement.

var View = Backbone.View.extend({
render: function() {
$(this.el).html(new Date().toLocaleTimeString());
return $(this.el);
}
});

var view = new View();

- Vue liée au DOM : testez en ligne sur jsfiddle.

- DOM lié à la vue : testez en ligne sur jsfiddle.

Ces deux techniques ont leurs avantages et leurs inconvénients. Pour ma part, je préconise la seconde solution.

IV-B - Les événements

Backbone.View permet de gérer les événements d'un nœud assez simplement. Munissez-vous de l'action souhaitée et du sélecteur et le tour est joué.

var View = Backbone.View.extend({
render: function() {
$(this.el).html(this.template);
return $(this.el);
},
events: {
'click #button1' : 'onClickButton1',
'hover .button2' : 'onHoverButton2'
},
onClickButton1 : function() {
alert('button1');
},
onHoverButton2: function() {
alert('button2');
}
});

Testez en ligne sur jsfiddle.

V - Exemple complet

Maintenant que vous connaissez les grandes lignes de Backbone.js, il est temps de vous fournir un exemple utilisant tous les composants vus précédemment.
Libre à vous de vous amuser à rajouter des fonctionnalités.

Testez en ligne sur jsfiddle.

VI - Pour aller plus loin

VI-A - Gestion des routes

Maintenant que nous pouvons réaliser des pages Web composées de Backbone.View, peut-on aussi facilement gérer les différents états d'une page et y lier une URL ?

Si j'évoque le sujet, il est évident que la réponse est positive. Backbone.Router permet de mettre en place cette démarche. Une URI est composée d'un nom de domaine (tatami.ippon.fr) et d'une ressource (/tatami/). Il est possible de rajouter à la suite une ancre délimitée par un dièse (#/timeline). C'est cette ancre que Backbone.Router utilise pour déterminer quel est l'état de la page demandée.

Pour illustrer ces propos, une fois authentifié sur la page d'accueil de Tatami, chaque onglet représente un état de la page. Il en existe cinq actuellement :

- "#/timeline", la page avec l'onglet "Status" affiché ;

- "#/favoris", la page avec l'onglet "Favoris" affiché ;

- "#/tags", la page avec l'onglet "Tags" affiché ;

- "#/search", la page avec l'onglet "Recherche" affiché ;

- "#/daily", la page avec l'onglet "Status du jour" affiché.

Source du router home de Tatami.

VI-B - Asynchronous Module Definition API

Il est possible d'utiliser Backbone.js avec un AMD Loader comme RequireJS ou Curl. Ni Backbone.js, ni Underscore ne supportent officiellement AMD. Toutefois, il est possible d'utiliser un fork implémentant cette API.

On trouve sur GitHub des projets templates (boilerplate) qui facilitent la mise en place d'un environnement couplant RequireJS et Backbone. En voici deux parmi tant d'autres :

- BackboneJS-AMD-Boilerplate ;

- Backbone-boilerplate.

VI-C - Plugins

Backbone.js se veut léger : il ne fournit que des composants essentiels. Un des gros manquements de Backbone.js par rapport à ses concurrents est l'absence de la fonctionnalité de DataBinding. Mais qu'à cela ne tienne, de nombreux plugins sont présents en libre accès sur GitHub, pour implémenter des fonctionnalités. Voici, quelques plugins que je trouve intéressants :

- Backbone.ModelBinder : implémentation du DataBinding ;

- Backbone.Marionette : collection de composants additionnels ;

- Backbone.localStorage : adaptateur localStorage.

VII - Conclusion

Je me suis occupé de la migration de Tatami vers une interface utilisant Backbone.js et son utilisation s'est révélée être très agréable et facilitée lorsqu'on le couple à une API RESTful JSON.

Vous pouvez accéder au code source de Tatami et voir comment Backbone.js peut être utilisé dans un projet.

Pour aller plus loin, je vous conseille de lire sur cet article qui explique les différentes étapes qui permettent de passer d'une application jQuery à une application utilisant Backbone.js.

VIII - Remerciements

Cet article a été publié avec l'aimable autorisation de Ippon technologies et d'Arthur WEBER. L'article original peut être vu sur le blog d'Ippon.