samedi 18 juin 2011

#Backbone.js: petit tutorial

L'intervention de  David Heinemeier Hansson à la Railsconf 2011 de Baltimore   évoquait un nouveau phénomène: l'apparition des MVC coté client. Ces MVC sont forcement en javascript, seul langage supporté par les navigateurs. Parmi les noms de MVC javascript, backbone.js est celui le plus cité.


Je me suis plongé pendant quelques jours sur la document de backbone , en particulier sur l'exemple de TODO List réalisé  par Jérôme Gravel-Niquet.

Reuven Lerner, éditorialiste  de la revue Linux Journal (US) a consacré deux series d'article sur le sujet (juin num 206 et juillet: num 207).
On   trouve ici et là  d'autres articles.



Conclusion : j'ai failli me noyer.



Les principes sont pourtant assez simples: La notion de modèle  recouvre l'accès aux données. Ces données sont récupérées par l'appel d'une URL  du serveur applicatif. La partie vue correspond à la partie visuelle: la portion de HTML.
La partie controleur est responsable de la gestion des 'routes'. Dans les applications massivement en AJAX, l'utilisateur voit plusieurs pages mais reste physiquement sur une page. Aussi le  developpeur peut utiliser les fragments d'url (/#monFragment) pour différentier artificiellement les pages pour la gestion des signets. Ce système fait appel aux 'routes' du controleur.

La partie controleur est réduite au minimum dans les petites applications javascript.

En revanche, le dialogue entre les couches est à  prendre en charge par le développeur. A ce dialogue s'ajoute les interractions avec jquery. Au final l'investissement initial n'est pas neutre.

La couche modèle.
Backbone propose une structure pour  définir et manipuler  des éléments  unitaires ou des collections d'élément.


Exemple :
    masuite.bind("add", function(v) {
    alert("Ahoy " + v.get("valeur") + "!");
    }); 
   var a= new UnElement({valeur:1});    
    var b= new UnElement({valeur:2});
    masuite.add(a);
    masuite.add(b,{silent:true});
 
Je commence par définir une fonction qui se déclenchera lors de chaque ajout d'un élément à une collection. L'option 'silent'  bloque la remontée de l'évènement.

La collection est la colonne vertébrale de votre application. L'utilisation de la librairie : underscore.js ajoute une vingtaine de méthodes supplémentaires dont le each , le tri, la comparaison entre deux états. La couche modèle est responsable des échanges de donnée avec le serveur.


La couche vue.

Il y aura en principe autant de vue que de portion d'affichage. Dans mon exemple, j'ai deux vues, une pour afficher l'élément unitaire de la suite, l'autre pour les informations relatives  à la suite de nombre (la collection).
Tout changement dans le modèle sera repercuté dans la vue.

Comment brancher le modèle à sa vue ? : les avis divergent. Doit on réferencer la vue dans le modèle , ou l'inverse ou les deux à la fois ?.
J'ai suivi l'exemple du TODOS liste.


Cela donne le code suivant:
 




Le html est très simple:


A chaque ajout d'un élément dans la collection toutes les vues se mettent à jour:


Cette application n'a pas besoin d'un vrai controleur.
Par comparaison j'ai réalisé cette application sans backbone.js , juste avec jquery.




La comparaison est sans appel : c'est plus compliqué et long à faire avec backbone.js. Mais en ajoutant des deux cotés des nouvelles fonctions, très vite je me suis rendu compte que l'ajout est plus simple à réaliser avec backbone.js.
Attention à l'ordre d'insertion des librairies javascript : jquery, underscore,backbone,mon_script.  
Les sources sont sur github.


5 commentaires:

tirabc a dit…
Ce commentaire a été supprimé par un administrateur du blog.
Eric German a dit…
Ce commentaire a été supprimé par l'auteur.
tirabc a dit…

Oui ok pour un serveur RESTFUL, mais existe-t-il une solution propre pour pouvoir repondre uniquement aux verbes GET POST (les seuls autorisés sur les hebergements mutualisés) tout en gardant un sens/esprit REST ?

Anonyme a dit…
Ce commentaire a été supprimé par un administrateur du blog.
Eric German a dit…
Ce commentaire a été supprimé par l'auteur.