IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Apprendre le data-binding dans Angular, React et Vue,
Un tutoriel de SylvainPV

Le , par Community Management

88PARTAGES

9  0 
Chers membres du club,

Je vous présente ce tutoriel de SylvainPV sur comprendre le data binding dans Angular, React et Vue.


Les frameworks MVVM sont aujourd'hui une partie centrale du développement front-end d'applications web. Ils occupent souvent l'actualité JavaScript et sont source de grands débats parmi les professionnels.

Derrière cette appellation, on retrouve un principe de base reliant le Modèle (M) à la Vue (V) : le data binding. Pourtant ce mécanisme est souvent mal connu ou mal compris par les utilisateurs de ces frameworks, perdus dans le jargon technique et marketing.

Nous allons tâcher de décrire comment ce mécanisme de data binding est implémenté au sein de trois frameworks populaires : Angular, React et Vue.
Bonne lecture

Les meilleurs cours et tutoriels pour apprendre la programmation JavaScript
Les meilleurs cours et tutoriels pour apprendre la programmation Web

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de Paleo
Membre éclairé https://www.developpez.com
Le 02/07/2016 à 9:52
L'approche de Monkberry semble saine : pas de data binding, pas de DOM virtuel, aucune magie.

Un langage de template :

Code : Sélectionner tout
1
2
3
<div>
  Hello {{ name }}!
</div>
… compilé en code JavaScript utilisant les objets DOM standards :

Code : Sélectionner tout
1
2
var div1 = document.createElement('div');
div1.textContent = 'Hello ' + name + '!';
1  0 
Avatar de SylvainPV
Rédacteur/Modérateur https://www.developpez.com
Le 05/07/2016 à 0:05
Intéressant. C'est bien du data-binding, à partir du moment où il y a des mises à jour partielles du DOM et une résolution des liaisons dans un modèle de données. Pour la magie c'est plus subjectif comme définition J'ai joué avec une petite heure, voilà mon analyse :

Pour la détection de changements, c'est du classique: une API de changement d'état à la React/Backbone. Le templating est DOM-based (on ne peut pas mettre d'expressions pour définir un tag par exemple), mais il y a les moustaches comme sucre syntaxique pour l'interpolation de texte et attributs.

Concernant la mise à jour du DOM, c'est plus particulier : la compilation du template consiste en fait à le faire passer par un parser HTML qui va écrire le code JS correspondant pour générer ce HTML à partir des API du DOM, avec le bon vieux document.createElement. Ces éléments sont créés un par un et assignés à des références en mémoire. Lorsque des liaisons de données sont détectées pour un élément, chaque donnée aura un setter associé qui fera les modifications sur l'élément en question. C'est un peu comme si vous écriviez vos mises à jour du DOM à la main, sauf que là c'est un compilateur qui s'en charge.

Un exemple vaut mieux qu'un long discours. Le template:
Code html : Sélectionner tout
1
2
3
4
5
6
7
  
<div> 
   <p> 
      Hello {{ name }}! 
   </p> 
   <p>Monkberry is <i>almost</i> an anagram of Monkey beer</p> 
</div>

est compilé en :

Code js : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/** 
 * @class 
 */ 
function hello() { 
  Monkberry.call(this); 
  
  // Create elements 
  var div0 = document.createElement('div'); 
  var p1 = document.createElement('p'); 
  var text2 = document.createTextNode(''); 
  var p3 = document.createElement('p'); 
  var i4 = document.createElement('i'); 
  
  // Construct dom 
  p1.appendChild(document.createTextNode(" Hello ")); 
  p1.appendChild(text2); 
  p1.appendChild(document.createTextNode("! ")); 
  i4.appendChild(document.createTextNode("almost")); 
  p3.appendChild(document.createTextNode("Monkberry is ")); 
  p3.appendChild(i4); 
  p3.appendChild(document.createTextNode(" an anagram of Monkey beer")); 
  div0.appendChild(p1); 
  div0.appendChild(p3); 
  
  // Update functions 
  this.__update__ = { 
    name: function (name) { 
      text2.textContent = name; 
    } 
  }; 
  
  // Set root nodes 
  this.nodes = [div0]; 
} 
hello.prototype = Object.create(Monkberry.prototype); 
hello.prototype.constructor = hello; 
hello.pool = []; 
hello.prototype.update = function (__data__) { 
  if (__data__.name !== undefined) { 
    this.__update__.name(__data__.name); 
  } 
}; 
  
window.hello = hello; 
//# sourceMappingURL=view.js.map

Les avantages et les inconvénients apparaissent alors clairement:

Avantages:
  • les mises à jour du DOM sont effectivement les plus minimales possibles, puisque chaque donnée a son setter dédié
  • le template une fois compilé reste lisible et exploitable en tant que tel


Inconvénients:
  • une fois compilé, le code est très, très verbeux. Avec cet exemple très simple on a multiplié par 10 la taille du code après compilation. Et plus les liaisons dans le template seront complexes, plus ce facteur risque d'augmenter.
  • il n'y a actuellement pas d'optimisation pour gérer les parties statiques des templates. Le second paragraphe est ainsi construit manuellement avec ses références sans que cela soit vraiment nécessaire.


Vu que la latence réseau reste le problème de perf numéro 1 pour l'usage web, le fait que la précompilation vienne décupler la taille des templates est un énorme désavantage, que le faible poids de la lib en elle-même peut difficilement compenser à lui seul (et puis afficher le poids gzippé c'est tricher :p ). A la rigueur, je peux y voir un intérêt pour les applications JS hors-ligne ou embarquées. Mais alors le faible poids de la lib n'est plus un argument en sa faveur non plus.

J'ai aussi de grosses craintes sur la résolution de divers problèmes tels que les boucles infinies ou la résistance aux modifications inopinées du DOM. C'est le genre de chose pour lesquels Angular/React/Vue ont des mécanismes dédiés, j'ai moi-même dû le faire sur mon side-project de lib de data-binding. Mais en l'état, j'ai l'impression que Monkberry ne fait rien de tout ça et se contente d'une sorte de transpilation template HTML --> JS bête et méchante.

Bref j'attends d'avoir plus de retours et des démos réelles d'applications pour juger, mais je suis très mitigé pour le moment.
1  0 
Avatar de Paleo
Membre éclairé https://www.developpez.com
Le 06/04/2016 à 12:24
Merci SylvainPV pour cet excellent aperçu des différentes solutions en data-binding.

Je trouve aussi que Vue.js est une solution légère et élégante en matière de data-binding. La question qui, en ce qui me concerne, n'est pas tranchée, est la suivante : le data-binding vaut-il réellement la peine, par rapport à une manipulation plus traditionnelle des éléments du DOM via Sizzle/jQuery ou même les API standards ?
0  0 
Avatar de SylvainPV
Rédacteur/Modérateur https://www.developpez.com
Le 06/04/2016 à 14:27
Tout dépend si tu optes pour un rendu des vues côté client ou côté serveur. Si l'essentiel de ton rendu est fait côté serveur, et que les interactions côté client ne sont pas trop complexes, une manipulation directe et manuelle du DOM est sans doute plus simple. En revanche, si le rendu est fait côté client, on a tout intérêt à se reposer sur une solution de data-binding afin que toutes les vues soient conditionnés par le modèle. Cela permet de limiter les états applicatifs et de simplifier énormément la gestion. Tu es déjà sûrement tombé dans le cas où tu as un plugin UI jQuery qui doit modifier le DOM pour s' "initialiser", et sur lequel tu dois toujours te poser la question de s'il est initialisé ou pas, ou "en cours d'initialisation". Ces "états" de vues n'existent plus quand tu pars sur une solution comme React ou vuex.

Si tu te rappelles de mon article sur le templating client, tu sais que je penche nettement en faveur du rendu côté client, pour la compensation de latence, la réduction de la bande-passante utilisée et l'ouverture à l'usage offline
0  0 
Avatar de Paleo
Membre éclairé https://www.developpez.com
Le 06/04/2016 à 15:33
Je parle aussi d'application JavaScript embarquée dans le navigateur. Le data-binding n'est pas un lien entre le modèle et la vue au sens MVC du terme. Il s'agit plutôt d'un moyen d'agir sur la vue au travers d'une représentation. Je veux dire que les modèles des vues ne sont pas le modèle de l'application, et la synchronisation entre les (modèles de) vues et le modèle de l'application est en dehors de la problématique du data-binding.

On peut programmer de manière modulaire, par "composants", c-à-d en regroupant le code CSS, les templates HTML et le code JS par petites entités fonctionnelles, tout en manipulant directement des éléments du DOM.
0  0 
Avatar de SylvainPV
Rédacteur/Modérateur https://www.developpez.com
Le 06/04/2016 à 16:30
Oui, on se rapproche alors davantage d'un pattern MVC que MVVM.
0  0 
Avatar de Paleo
Membre éclairé https://www.developpez.com
Le 24/05/2016 à 22:00
Pour info : https://engineering.footballradar.co...-tabular-data/
0  0 
Avatar de Paleo
Membre éclairé https://www.developpez.com
Le 05/07/2016 à 14:04
Merci pour l'analyse.

Citation Envoyé par SylvainPV Voir le message
C'est bien du data-binding, à partir du moment où il y a des mises à jour partielles du DOM et une résolution des liaisons dans un modèle de données.
Le data binding n'implique-t-il pas par définition une synchronisation automatisée ? Ici, après chaque modification des données, il faut faire un :

Code : Sélectionner tout
view.update(state);
Citation Envoyé par SylvainPV Voir le message
C'est un peu comme si vous écriviez vos mises à jour du DOM à la main, sauf que là c'est un compilateur qui s'en charge.
C'est-à-dire que Monkberry donne un langage de template à ceux qui veulent gérer des morceaux du DOM à l'ancienne.

Citation Envoyé par SylvainPV Voir le message
Vu que la latence réseau reste le problème de perf numéro 1 pour l'usage web, le fait que la précompilation vienne décupler la taille des templates est un énorme désavantage
Ah, effectivement. D'expérience, en ce qui me concerne, le poids des templates dans une application JS n'est pas énorme relativement au code JS, mais c'est un point à vérifier.

Citation Envoyé par SylvainPV Voir le message
J'ai aussi de grosses craintes sur la résolution de divers problèmes tels que les boucles infinies ou la résistance aux modifications inopinées du DOM. C'est le genre de chose pour lesquels Angular/React/Vue ont des mécanismes dédiés, j'ai moi-même dû le faire sur mon side-project de lib de data-binding. Mais en l'état, j'ai l'impression que Monkberry ne fait rien de tout ça et se contente d'une sorte de transpilation template HTML --> JS bête et méchante.
Boucles infinies : il faudrait que je vois un exemple, je ne comprends pas où est le risque.
Pour les modifications inopinées du DOM : il me semble aussi que rien n'est géré.
0  0 
Avatar de SylvainPV
Rédacteur/Modérateur https://www.developpez.com
Le 05/07/2016 à 16:30
Il faut voir ce que l'on entend par "synchronisation automatisée". Je décompose ça en trois points: détection de changements, résolution des liaisons et mise à jour du DOM. Le data-binding désigne surtout la partie intermédiaire qui relie modèle et DOM, à partir de là on a des techniques de change detection et de mises à jour du DOM très différentes selon les solutions comme vu dans l'article. Les React / Redux / Vuex et autres Flux-based fonctionnent tous avec une API de changement d'état par exemple.

Pour les boucles infinies j'en parle en début de l'article.
0  0 
Avatar de Paleo
Membre éclairé https://www.developpez.com
Le 05/07/2016 à 21:35
Citation Envoyé par SylvainPV Voir le message
Pour les boucles infinies j'en parle en début de l'article.
Le 2-way data binding pose plusieurs problématiques, dont la principale est celle de provoquer des boucles infinies dans certains cas. Un match de ping-pong peut survenir lorsqu'une mise à jour du modèle entraîne une mise à jour de la vue qui elle-même entraîne une mise à jour du modèle, qui elle-même entraîne une mise à jour de la vue, etc.
Sauf erreur, cette problématique est en dehors du scope de Monkberry, puisqu'il n'y a pas de détection des changements. Et pas non plus de mise à jour automatisée d'un état à partir de valeurs d'un formulaires. Ici, c'est au développeur de faire attention à ce qu'il fait.
0  0