La communication entre components Knockout

Auteur du billet de blog : Xavier Noya - Neotech Solutions

Xavier Noya

Ingénieur d'études
  Publié le vendredi 22 septembre 2017

Curieux, passionné et sensible à l'expérience utilisateur, je suis un jeune développeur qui apprécie autant les technologies Front que Back, que ce soit pour le web, sur mobile ou desktop

Dans ce billet, nous allons voir ensemble une solution simple et rapide à mettre en place pour faire communiquer vos différents composants Knockout JS.

Rappel

Knockout JS est une librairie JavaScript toute légère, qui va vous permettre de dynamiser vos vues. Pour faire simple, cette librairie permet d'associer des modèles de données à des éléments de votre vue grâce à des bindings. Elle s'appuie sur le pattern MVVM : Model - View - ViewModel, un design pattern introduit par Microsoft à l'origine pour les applications WPF. Celui-ci permet une meilleure séparation des données, de la vue et de la logique.

Knockout, pour la sortie de sa version 3.2, va introduire les "Components". Ce sont, comme le nom l'indique, des composants qui vont nous permettre d'organiser votre UI en petits blocs encapsulés, autonomes et réutilisables. En combinant un viewmodel à un template, l'UI est propre, bien organisée, et facile à maintenir. Fini les viewmodels à rallonge, vive les components !

La communication

Dans certaines situations, il se peut que vous soyez obligé de faire communiquer vos components entre eux. Knockout rend ceci possible entre des composants parents et enfants :

De cette manière, l'observable du parent sera accessible depuis le component enfant et une modification sur ce dernier entraînera une modification côté parent. Super pratique dans des cas simples, mais il se peut que pour les besoins de votre application, vous vous retrouviez avec un parent comportant plusieurs enfants, qui eux mêmes possèdent plusieurs components enfants, avec un bon nombre de paramètres à faire descendre entre les différentes "couches". Cela peut devenir vite compliqué et difficile à maintenir et cela crée une interdépendance entre les composants. Une autre problématique se pose, comment faire lorsque nos composants sont totalement isolés les uns des autres ?

Il existe bel et bien une solution pour faire cela. Il faut creuser autour du mécanisme de subscribe proposé par Knockout pour pouvoir faire ce que l'on souhaite. En effet, Knockout met en avant un système de subscribe, qui nous permet d'être notifié des changements de nos observables. On peut même souscrire à un évènement spécifique pour être notifié à l'avance, avant que le changement opère.

Dans l'exemple ci-dessus, on s'inscrit à l'évènement "beforeChange" qui sera lancé avant que l'observable prenne sa nouvelle valeur. C'est ce système de publish/subscribe que nous allons utiliser pour communiquer entre nos composants en créant nos propres événements. Comme nous pouvons le voir dans le code source de Knockout, nous pouvons instancier un "subscribable" pour pouvoir à la fois notifier et identifier les composants qui écoutent. Il faut que le subscribable instancié soit accessible partout dans l'application. Si vous utilisez RequireJs pour faire de l'Asynchronous Module Definition (AMD), il est conseillé d'encapsuler un viewModel de base que vous injecterez dans tous vos autres viewModels pour pouvoir accéder au subscribable partout.

Voici comment procéder, étape par étape :

1) Déclaration du subscribable :

2) Dans notre component qui va écouter, on souscrit à un évènement custom :

3) Dans le component qui va envoyer l'information, on notifie les subscribers en prenant soin de préciser le nom de l’événement custom que l'on utilise dans le composant qui écoute :

Et voilà, le tour est joué ! Plutôt simple non ? Voici pour vous un exemple complet :