Dans le dernier article, nous avons présenté les bases de Backbone Views et comment permettre à jQuery de manipuler de manière transparente le même DOM que Backbone..
Dans cet article, nous verrons comment faire en sorte que Backbone joue bien avec d3.js. Les concepts de cet article doivent s'appliquer aux situations dans lesquelles vous avez l'intention d'utiliser Backbone avec la plupart des autres bibliothèques qui manipulent également le DOM..
d3.js, écrit par Mike Bostock, est une autre bibliothèque largement utilisée qui manipule le modèle objet de document, principalement pour visualiser des données. En fait, vous pouvez être vraiment créatif avec la façon dont les données peuvent être visualisées.
Au niveau le plus bas, d3.js interagit avec les éléments HTML et / ou SVG et manipule leurs attributs en liant les données au modèle d'objet document.
Voici un exemple rapide du fonctionnement de d3:
var numericalData = [1,2,3,4,5,6]; d3.select ("body"). selectAll ("p") .data (numericalData) .enter () .append ("p") .text (fonction (d) retourne "je suis un nombre" + d + " ! ";);
Le code ci-dessus fait ce qui suit:
corps
élémentp
éléments actuellement dans le DOMdonnees numeriques
à un sélectionné p
élémentp
élément qui doit encore exister (c.-à-d. certains éléments de donnees numeriques
qui doivent encore être ajoutés), crée un p
élément et l'ajoute le DOMp
élément contenant du texte (y compris le numéro correspondant dans donnees numeriques
)Tirant parti de ce que nous avons appris dans le précédent article, voici une implémentation d’une manipulation partagée du DOM.
var CoolView = Backbone.View.extend (render: function () var html = "Je ne suis pas un nombre!
"; this. $ el.html (html); retour this;, renderVisualization: function (arrayOfData) d3.select (" body ") .selectAll (" p ") .data (arrayOfData) .enter () .append ("p") .text (fonction (d) retourne "je suis un nombre" + d + "!";);); var coolView = nouveau CoolView (); coolView.render (); var myData = [10, 9, 4, 2, 1]; coolView.renderWithD3 (myData);
En supposant que notre objectif soit de préserver le p
élément et ajouter l'autre p
éléments de DOM, lorsque nous exécutons le code ci-dessus, nous rencontrons rapidement un problème majeur.
le .rendre()
inserts une p
élément avec le texte "je ne suis pas un nombre" dans le DOM. Mais .renderVisualization ()
sélectionne tous les existants p
éléments dans le DOM et insère un contenu dans ces éléments. Ce écrase le texte de l'original p
élément, malgré notre annexant au DOM en utilisant d3.append ()
.
Dans cet exemple simple, au moins deux solutions simples existent.
Pour des exemples plus complexes, nous aurons peut-être besoin de stratégies alternatives. Une solution potentielle consiste à isoler une partie du DOM qui sera exploitée par l'une des bibliothèques. Par exemple:
var CoolView = Backbone.View.extend (… renderVisualization: function (arrayOfData) d3.select ("# visualisation") .selectAll ("p") .data (arrayOfData) .enter () .append ("p") .text (fonction (d) retourne "je suis un nombre" + d + "!";);)); var coolView = new CoolView (); var myData = [10, 9, 4, 2, 1]; coolView.renderVisualization (myData);
Dans le cas ci-dessus, Backbone continue de gérer la vue à créer. Cependant, disons qu’il existe un élément quelque part dans le DOM (à l’intérieur de ou en dehors du DOM géré par la vue Backbone) dont l’identifiant est «visualisation». Nous pouvons capitaliser sur ce fait en analysant toutes nos manipulations DOM liées à d3 à cet élément. En conséquence, toutes les méthodes en chaîne d3, y compris .selectAll ("p")
et .append ("p")
, sont exécutés dans le contexte de #visualisation
.
Enfin, une autre approche de la gestion des fonctionnalités d'affichage tierces consiste à utiliser des sous-vues. Voici à quoi cela pourrait ressembler.
var CoolView = Backbone.View.extend (render: function () var subViewA = new SubViewA (); var subViewB = new SubViewB (); // définit le contenu html pour coolview this. $ el.html (subViewA.render () .el); // ajoute plus de contenu HTML à coolview this. $ el.append (subViewB.render (). el); return this;); // Ailleurs, peut-être dans votre routeur… var coolView = new CoolView (); $ ('. app'). html (coolView.render (). el);
Dans ce scénario, sous-vueA
peut contenir du contenu non visuel, et subViewB
peut contenir du contenu de visualisation.
Il arrive parfois que vous deviez vous assurer que votre manipulation DOM d3 se produit dans le même contexte que la vue Backbone elle-même. Par exemple, il suffit de boucler une partie du DOM avec #visualisation
n'offre aucune garantie que l'élément existe à l'intérieur ou à l'extérieur de la partie du DOM représentée par la vue Backbone.
Une alternative consiste à vous assurer que votre sélection de d3 de départ référence le même élément que celui indiqué par ceci. $ el
. Cependant, si vous avez tendance à ne pas définir el
ou l'un de ses attributs directement, il serait difficile de cibler suffisamment la vue actuelle à l'aide de CSS.
Heureusement, dans la bibliothèque d3.js, il existe une méthode permettant la sélection directe des nœuds. Permettez-moi de vous présenter à d3.select (noeud)
. Selon la documentation, cette méthode:
Sélectionne le noeud spécifié. Cela est utile si vous avez déjà une référence à un nœud, tel que d3.select (this) dans un écouteur d'événement, ou un élément global tel que document.body. Cette fonction ne traverse pas le DOM.
Cette méthode nous permet d’écrire le code suivant et d’assurer que les manipulations d3 se produisent dans le contexte de la vue Backbone..
var CoolView = Backbone.View.extend (// notez que "el" n'est pas défini directement. render: function () var html = "Je ne suis pas un nombre!
"; this. $ el.html (html); return this;, renderVisualization: function (arrayOfData) d3.select (this); // ne fonctionnera pas," this "fait référence à un objet de réseau principal d3.select (this .el) // passe une référence de noeud .selectAll ("p") .data (arrayOfData) .enter () .append ("p") .text (fonction (d) retourne "I'm number" + d + "!";););
En résumé, il y a un certain nombre de considérations à prendre en compte pour que Backbone fonctionne bien avec d'autres manipulateurs DOM..
Il existe également plusieurs solutions à envisager, en fonction du résultat recherché: