Quoi choisir quand on n’est pas enthousiaste pour Angular, que Svelte est décevant et que Backbone n’est plus mis à jour?

Introduction

Toujours dans ma recherche d’un framework Javascript capable de remplacer jQuery (voir ici). Quoi choisir quand on n’est pas enthousiaste pour Angular, que Svelte est décevant et que Backbone n’est plus mis à jour? J’ai trouvé le framework KnockOut.js. Voyons voir ce que ça vaut.

C’est quoi KnockOut.js?

Il s’agit d’un framework qui propose une implémentation du pattern MVVM (Model-View-ViewModel) dont la syntaxe est “normale” (comprendre “non JSX”). Cet article (en anglais) présente les trois concepts MVC, MVP et MVVP et leurs différences. Les autres caractéristiques du framework sont: open source (licence MIT), javascript pure, léger (66Kb), sans dépendance. Franchement ça me plaît bien.

Concepts exposés par Knockout

Les concepts sont simples: Model, View, ViewPresenter et routage (pour le SPA).

Concept du Model

C’est sans doute le plus simple puisque le Model représente les données (comme une entity en Java avec JPA/Hibernate).

Concept de View

Ici on parle du modèle de rendu que KnockOut mettra à jour pour afficher les données.

Concept de ViewModel

La dernière couche du MVVM permet de connecter la Vue et le Model. La vue reçoit les événements utilisateurs (clic, modification de champ par exemple) puis les transmet au ViewModel et qui décide la logique à mettre en œuvre.

Le routage

Ici KO.js propose deux solutions. La première est identique à celle proposée Angular et Svelte, on peut associer des urls aux composants et passer de l’un à l’autre, ce qui permet de réaliser une Single Page Application. A priori je ne vais pas développer ce point, je pense que le comportement sera le même qu’avec Svelte et sera incompatible avec Tomcat.

La deuxième solution est plus intéressante puisqu’on peut router directement entre les ViewModels. On peut donc réaliser une SPA sans être incompatible avec un serveur Web.

Les manques de KnockOut

Comme beaucoup de frameworks Javascript, la séparation réelle entre Model et ViewModel existe mais n’est jamais vraiment mise en avant.

Si on prend le premier exemple du tutoriel, on obtient le code suivant:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>

function AppViewModel() {
    this.firstName = "Bert";
    this.lastName = "Bertington";
}

// Activates knockout.js
ko.applyBindings(new AppViewModel());

On voit clairement que la View et le ViewModel sont séparés mais le ViewModel embarque les données qui devraient se trouver dans le Model. Il faut donc ajouter les couches nécessaires pour faire communiquer les ViewModels et les Models.

Un autre manque, comme dans les autres frameworks, est l’absence de structure des appels au back-end. KnockOut propose bien sûr de piloter des appels Ajax mais il n’y a aucun lien entre cet appel, le Model et la répercussion dans le ViewModel (si on charge des données du back-end, elles doivent être stockées dans le Model puis le ViewModel doit s’en servir pour mettre à jour la vue).

Extension du framework

Afin d’unifier les pratiques et donc économiser du temps de développement et beaucoup de maintenance, il faut outiller KnockOut avec les concepts suivants:

  1. Une classe utilitaire pilotant les appels au back-end (REST ou non)
  2. Une classe Model de base qui implémente le vocabulaire CRUD (Create, Read, Update, Delete) et qui permet de contrôler la validité des données avant envoi.
  3. Une classe ViewModel de base qui gère effectivement le lien entre Model et View et permet d’afficher les données, les modifier et afficher les messages d’erreurs identifés par le Model ou le back-end.

En plus de ces trois éléments de base, je vais ajouter une classe décrivant la notion d’application et une autre classe décrivant ce qu’est page au sein de l’application.

Conclusion

Knockout est un bon framework MVVM, plutôt simple à prendre en main et bien adapté pour réaliser des applications Web SPA (ou non). Comme la plupart des frameworks du même type, il manque une couche de liaison avec le back-end. En soi, c’est loin d’être rédhibitoire puisque c’est assez simple à faire et qu’on peut l’adapter pile-poil à son back-end.
Ma série d’articles sur le choix d’un framework Javascript se termine ici, le grand gagnant étant KnockOut. Pour les prochains articles, on se fait encore du Javascript autour de KnockOut ou on part sur du Java (là je m’enquiquine à faire de l’injection de dépendances sans Spring)?