Knockout.js et pager.js : des frameworks javascript faciles d’utilisation

Geddy, YUI App Framework, derby, meteor, ember.js… Voilà les quelques frameworks javascript qui m’ont paru mériter une exploration. J’ai été à la fois étonné par leurs possibilités et déçu par leur complexité qui m’a souvent paru inutile au regard des simples besoins des applications que je développe. J’en ai finalement retenu un, et j’admets avoir honte de ne l’avoir découvert que récemment. Il s’agit de knockout.js, un framework qui permet d’utiliser le modèle MVVM dans la création d’application client en javascript.

La documentation, bien qu’en anglais, est d’une simplicité assez difficile à égaler. Je n’entreprendrai donc pas un tutoriel sur son utilisation. Je tenterai plutôt de vous expliquer très simplement son fonctionnement et vous comprendrez comment il peut vous aider dans votre développement. J’aborderai ici le modèle MVVM et ses particularités pour le Web, le fonctionnement de base de knockout.js et, en dernier, comment gérer les URLs avec pager.js, le bras droit de knockout.js.

Le modèle MVVM

MVVM signifie Modèle Vue Vue-Modèle. C’est une variante de l’organisation MVC (Modèle Vue Contrôleur). Pour rappel, dans le modèle MVC :

  • Le modèle est l’instance qui contient les différentes données qui alimentent l’application. C’est, sensiblement, le schéma d’une base de données.
  • La vue est l’instance qui contient le rendu visuel. Dans une application Web, on parle de templates.
  • Le contrôleur fait le lien entre le modèle et la vue. C’est lui qui détermine quelles données doivent être passées et à quelle vue elles doivent l’être.

Le modèle MVVM fonctionne un peu de la même façon, à la différence que le rôle du contrôleur est assumé partiellement par ce que l’on appelle une Vue-Modèle. Ici, je crois qu’une explication est de mise ! Dans knockout.js :

  • Ne cherchez pas le « M » de « MVVM » dans knockout.js. On ne retrouve pas de modèle en tant que tel. Dans une application construite avec knockout.js, le modèle, s’il existe, se trouve sur le serveur. Personnellement, je trouve cela très logique. Dans des applications Web, le modèle sur l’application client est souvent une version épurée et partielle du modèle sur le serveur.
  • Les vues sont écrites directement en HTML et knockout.js se charge de sélectionner les portions de code à afficher.
  • Les Vues-Modèles sont des objets javascript dont les propriétés peuvent être affichées dans les vues et dont les fonctions peuvent être appelées suite à des événements. Contrairement au constructeur dans MVC, les Vues-Modèles ne commandent l’affichage d’aucun template.

Fonctionnement de base et exemple

Pour l’installation, sachez qu’il suffit d’inclure le fichier javascript de knockout.js que vous pouvez télécharger ici : http://knockoutjs.com/downloads/

Dans votre HTML, simplement :

  

Prenez ce code HTML en exemple :

Nom :
Prénom :

Et ce code javascript, avant votre :

var ViewModel = function() {  
  this.nom = ko.observable('Lepage');
  this.prenom = ko.observable('Alexandre');

  this.nomComplet = ko.computed(function() {
    return this.prenom + ' ' + this.nom;
  }, this);
};

ko.applyBindings(new ViewModel());  

Vous remarquez que le contenu du

est automatiquement mis à jour selon ce que vous entrez dans les champs de texte. Quelques explications s’imposent :

  • ko.observable() sert à définir des propriétés dont la valeur peut changer (par exemple, en modifiant le contenu d’un champ de formulaire, en rechargeant des données depuis le serveur, etc.).
  • ko.computed() sert à définir une propriété dont la valeur est générée par l’appel d’une fonction (passée en paramètre). Il y a là une des grandes forces de knockout.js : à l’intérieur de cette fonction, il détectera automatiquement quelles propriétés sont utilisées (prenom et nom dans ce cas-ci). Lorsque l’une d’elles est modifiée, la fonction est rappelée.
  • L’attribut data-bind sert à déterminer à quelles conditions et comment est affiché l’élément HTML. Ici, le binding text sert à définir à partir de quelle propriété le contenu de la balise sera généré et le binding value synchronise la valeur du input avec celle de la propriété.

Je relis ces quelques explications, et je conçois parfaitement qu’elles puissent être obscures ou insuffisantes si vous n’êtes pas familiers avec knockout.js. Je vous renvoie donc à ce tutoriel interactif qui, en 30 minutes, vous fera tout saisir : http://learn.knockoutjs.com/.

Je le répète, la véritable force de knockout.js réside dans sa capacité à retracer les dépendances partout dans votre code. Si vous modifiez une variable, peu importe dans quelles circonstances, knockout.js modifiera votre interface conséquemment.

Des SPA avec pager.js

SPA = Single Page Application (il faut le rappeler !). Ultimement, l’idée est que tout l’affichage des pages soit géré par l’application côté client, et que les interactions avec le serveur se limitent à des échanges de données (avec un API RESTful idéalement).

Pager.js ajoute simplement à knockout.js le binding page qui permet d’associer un code HTML à une URL. Tout simplement. Rien d’autre (enfin, il y a bien des utilisations avancées, mais ne nous compliquons pas la vie !). Il vous suffit d’inclure le fichier javascript (en dernière version, disponible sur github : https://github.com/finnsson/pagerjs/blob/master/pager.js).

Modifiez votre javascript de tout à l’heure :

var app = new ViewModel();  
pager.extendWithPage(app);  
ko.applyBindings(app);  

Et essayez ce HTML :

  

Index

À propos

La documentation de pager.js a l’avantage d’être tout simplement parfaite. Commencez par ce démo qui vous explique, étape par étape, comment fonctionne la page sur laquelle vous vous trouverez.

Conclusion

Pour conclure, je ne peux que vous référer aux excellentes documentations de knockout.js et de pager.js. Contrairement à, par exemple, ember.js, knockout.js ne m’a encore jamais mis dans une situation où je n’avais réellement aucune idée sur la façon d’accomplir quelque chose. C’est un framework non contraignant, facile à utiliser et très bien documenté. Venant de quelqu’un qui déteste les frameworks javascript… c’est parlant ! En français, je vous recommande aussi cet article qui introduit knockout.js un peu plus longuement.