Veuillez considérer cette question comme strictement éducative. Je suis toujours intéressé par de nouvelles réponses et de nouvelles idées pour mettre en œuvre ce projet.
tl;dr
Comment mettre en œuvre la liaison de données bidirectionnelle avec JavaScript ?
Liaison de données au DOM
Par liaison de données au DOM, je veux dire par exemple, avoir un objet JavaScript a
avec une propriété b
. Ensuite, avoir un <input>
élément du DOM (par exemple), lorsque l'élément du DOM change, a
et vice versa (c'est-à-dire que je parle de liaison bidirectionnelle des données).
Voici un diagramme d'AngularJS sur ce à quoi cela ressemble :
Donc, en gros, j'ai un JavaScript similaire à :
var a = {b:3};
Puis un élément de saisie (ou autre formulaire) comme :
<input type='text' value=''>
Je voudrais que la valeur de l'entrée soit a.b
(par exemple), et lorsque le texte de l'entrée change, je voudrais que a.b
de changer aussi. Quand a.b
change en JavaScript, l'entrée change.
La question
Quelles sont les techniques de base pour y parvenir en JavaScript ?
Plus précisément, j'aimerais avoir une bonne réponse à laquelle me référer :
- Comment la liaison fonctionnerait-elle pour les objets ?
- Comment écouter le changement de forme pourrait-il fonctionner ?
- Est-il possible, de manière simple, de ne faire modifier le HTML qu'au niveau du modèle ? J'aimerais ne pas garder la trace de la liaison dans le document HTML lui-même, mais seulement en JavaScript (avec des événements DOM, et JavaScript gardant la référence aux éléments DOM utilisés).
Qu'est-ce que j'ai essayé ?
Je suis un grand fan de Mustache, j'ai donc essayé de l'utiliser comme modèle. Cependant, j'ai rencontré des problèmes lorsque j'ai essayé d'effectuer la liaison de données elle-même, car Mustache traite le HTML comme une chaîne de caractères, de sorte qu'après avoir obtenu son résultat, je n'ai aucune référence à l'emplacement des objets de mon modèle de vue. La seule solution à laquelle j'ai pu penser était de modifier la chaîne HTML (ou l'arbre DOM créé) elle-même avec des attributs. Cela ne me dérange pas d'utiliser un autre moteur de création de modèles.
En fait, j'ai eu le sentiment que je compliquais le problème et qu'il existait une solution simple.
Nota: Veuillez ne pas fournir de réponses qui utilisent des bibliothèques externes, en particulier celles qui représentent des milliers de lignes de code. J'ai utilisé (et j'aime !) AngularJS et KnockoutJS. Je ne veux vraiment pas de réponses du type "utilisez le framework x". Idéalement, j'aimerais qu'un futur lecteur qui ne sait pas comment utiliser de nombreux frameworks saisisse lui-même comment mettre en œuvre le data-binding bidirectionnel. Je n'attends pas d'un complet réponse, mais une qui fait passer l'idée.
2 votes
Je me suis basé CrazyGlue sur la conception de Benjamin Gruenbaum. Il prend également en charge les balises SELECT, checkbox et radio. jQuery est une dépendance.
19 votes
Cette question est totalement géniale. Si elle est fermée parce qu'elle est hors sujet ou pour d'autres raisons absurdes, je serai très mécontent.
0 votes
@JohnSz merci d'avoir mentionné votre projet CrazyGlue. Cela fait longtemps que je cherche un simple liant de données à deux voies. Il semble que tu n'utilises pas Object.observe, donc le support de ton navigateur devrait être excellent. Et comme tu n'utilises pas le templating mustache, c'est parfait.
0 votes
@Benjamin Qu'avez-vous fini par faire ?
0 votes
@johnny à mon avis la bonne approche est de créer le DOM en JS (comme React) et non l'inverse. Je pense qu'à terme, c'est ce que nous ferons.
0 votes
@BenjaminGruenbaum Cela signifie-t-il que le JS "intercepte" ou prend tout ce qui est renvoyé par le serveur et recrée ce que le serveur a envoyé, toutes les balises, tout ?
0 votes
@johnny JS rend le DOM sur le serveur et monte ensuite le DOM sur le client. Le client peut également effectuer le rendu à partir de zéro. La partie amusante est que vous obtenez des chargements instantanés avec un JS complet.
0 votes
De la part d'un futur lecteur, merci !
1 votes
De l'année 2021 -> merci pour cette question et les discussions !@##