+ Répondre à la discussion Actualité déjà publiée
  1. #1
    Community Manager

    Avatar de Siguillaume
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    août 2007
    Messages
    4 532
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : août 2007
    Messages : 4 532
    Points : 23 023
    Points
    23 023

    Par défaut [Article] Comprendre le data binding dans Angular, React et Vue

    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
    Vous avez envie de contribuer au sein du Club Developpez.com ? Contactez-nous maintenant !
    Vous êtes passionné, vous souhaitez partager vos connaissances en informatique, vous souhaitez faire partie de la rédaction.
    Il suffit de vous porter volontaire et de nous faire part de vos envies de contributions :
    Rédaction d'articles/cours/tutoriels, Traduction, Contribution dans la FAQ, Rédaction de news, interviews et témoignages, Organisation de défis, de débats et de sondages, Relecture technique, Modération, Correction orthographique, etc.
    Vous avez d'autres propositions de contributions à nous faire ? Vous souhaitez en savoir davantage ? N'hésitez pas à nous approcher.

  2. #2
    Membre confirmé
    Avatar de Paleo
    Homme Profil pro
    Développeur Web
    Inscrit en
    septembre 2013
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : septembre 2013
    Messages : 193
    Points : 556
    Points
    556

    Par défaut

    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 ?

  3. #3
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    novembre 2012
    Messages
    3 124
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : novembre 2012
    Messages : 3 124
    Points : 9 130
    Points
    9 130

    Par défaut

    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
    One Web to rule them all

  4. #4
    Membre confirmé
    Avatar de Paleo
    Homme Profil pro
    Développeur Web
    Inscrit en
    septembre 2013
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : septembre 2013
    Messages : 193
    Points : 556
    Points
    556

    Par défaut

    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.

  5. #5
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    novembre 2012
    Messages
    3 124
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : novembre 2012
    Messages : 3 124
    Points : 9 130
    Points
    9 130

    Par défaut

    Oui, on se rapproche alors davantage d'un pattern MVC que MVVM.
    One Web to rule them all

  6. #6
    Membre confirmé
    Avatar de Paleo
    Homme Profil pro
    Développeur Web
    Inscrit en
    septembre 2013
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : septembre 2013
    Messages : 193
    Points : 556
    Points
    556

  7. #7
    Membre confirmé
    Avatar de Paleo
    Homme Profil pro
    Développeur Web
    Inscrit en
    septembre 2013
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : septembre 2013
    Messages : 193
    Points : 556
    Points
    556

    Par défaut

    L'approche de Monkberry semble saine : pas de data binding, pas de DOM virtuel, aucune magie.

    Un langage de template :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <div>
      Hello {{ name }}!
    </div>
    … compilé en code JavaScript utilisant les objets DOM standards :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var div1 = document.createElement('div');
    div1.textContent = 'Hello ' + name + '!';

  8. #8
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    novembre 2012
    Messages
    3 124
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : novembre 2012
    Messages : 3 124
    Points : 9 130
    Points
    9 130

    Par défaut

    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 - Visualiser dans une fenêtre à part
    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 - Visualiser dans une fenêtre à part
    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.
    One Web to rule them all

  9. #9
    Membre confirmé
    Avatar de Paleo
    Homme Profil pro
    Développeur Web
    Inscrit en
    septembre 2013
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : septembre 2013
    Messages : 193
    Points : 556
    Points
    556

    Par défaut

    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 :

    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é.

  10. #10
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    novembre 2012
    Messages
    3 124
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : novembre 2012
    Messages : 3 124
    Points : 9 130
    Points
    9 130

    Par défaut

    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.
    One Web to rule them all

  11. #11
    Membre confirmé
    Avatar de Paleo
    Homme Profil pro
    Développeur Web
    Inscrit en
    septembre 2013
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : septembre 2013
    Messages : 193
    Points : 556
    Points
    556

    Par défaut

    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.

  12. #12
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    novembre 2012
    Messages
    3 124
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : novembre 2012
    Messages : 3 124
    Points : 9 130
    Points
    9 130

    Par défaut

    Le fait que Monkberry ne fasse pas de 2-way data-binding réduit les risques, c'est sûr, mais il y a d'autres manières de provoquer des boucles infinies: listeners d'évènements, hooks, setters... . La raison pour laquelle j'associe 2-way d-b avec boucles infinies dans l'article, c'est que ce mécanisme induit beaucoup d'opérations discrètes qui peuvent échapper au développeur et le surprendre, d'où l'émergence de bugs / boucles infinies. Mais ce n'est pas le 2-way d-b qui est à l'origine du problème, c'est juste un facteur aggravant car plus complexe à appréhender par le développeur. Au final, c'est toujours au développeur de faire attention et de se corriger, qu'il y ait un mécanisme de prévention ou non.

    Pour reprendre l'exemple de l'article avec Monkberry et provoquer une boucle infinie de façon naïve : http://jsfiddle.net/65re07Ls/1/
    One Web to rule them all

Discussions similaires

  1. Réponses: 3
    Dernier message: 24/02/2011, 14h46
  2. Réponses: 2
    Dernier message: 10/09/2010, 16h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo