Backbone Views și DOM Partea 2

În ultimul articol, am acoperit elementele de bază ale Vizualizărilor din Backbone și cum să activați jQuery pentru a manipula fără probleme același DOM pe care o manipulează Backbone.

În acest articol, vom explora modul în care putem face Backbone să joace frumos cu d3.js. Conceptele din acest articol trebuie să se aplice situațiilor în care intenționați să utilizați Backbone cu cele mai multe alte biblioteci care manipulează și DOM.

Backbone + d3.js Lucrul pe același DOM

d3.js, scris de Mike Bostock, este o altă bibliotecă pe scară largă care manipulează Modelul Obiectului de Document, în primul rând pentru vizualizarea datelor. De fapt, puteți obține cu adevărat creativitate cu modul în care datele pot fi vizualizate.

La cel mai scăzut nivel, d3.js interacționează cu elementele HTML și / sau SVG și manipulează atributele lor prin legarea datelor în Model Object Document.

Iată un exemplu rapid de funcționare a d3:

var numericalData = [1,2,3,4,5,6]; (d) return "Sunt numar" + d + "(d) Selectați (" p ") .Data (numericalData) .enter () ! ";); 

Codul de mai sus face următoarele:

  1. Selectează și creează o referință la corp element
  2. În această selecție, selectează toate p elemente aflate în prezent în DOM
  3. Se atașează fiecare element în date numerice la o selecție selectată p element
  4. Pentru fiecare p element care încă nu există (adică, unele elemente în date numerice care trebuie încă să fie adăugate), creează o p element și îl adaugă DOM
  5. Setează nodul text în fiecare nou creată p element pentru a conține un text (inclusiv numărul relevant din date numerice)

O primă încercare de a face Backbone și d3.js să joace frumos

Folosind ceea ce am învățat în articolul precedent, aici este o implementare a unei manipulări DOM comune.

var CoolView = Backbone.View.extend (render: function () var html = "

Nu sunt un număr!

", acest lucru: $ el.html (html); retur acest;, renderVisualization: function (arrayOfData) d3.select (" body ") .selectAll (" p ") .data (arrayOfData) ("p") .text (functie (d) retur "Sunt numar" + d + "!");); var coolView = new CoolView = [10, 9, 4, 2, 1]; coolView.renderWithD3 (myData);

Houston, am avut o problemă!

Presupunând că scopul nostru este de a păstra existența p și adăugați celelalte p elemente pentru DOM, atunci când executam codul de mai sus, ne confruntăm rapid cu o problemă majoră.

.face() inserții A p element cu textul "Eu nu sunt un număr" în DOM. Dar .renderVisualization () selectează toate cele existente p elemente din DOM și inserează conținut în elementele respective. Acest supra-scrieri textul din original p element, în ciuda noastră alăturarea la utilizarea DOM d3.append ().

Soluții pentru a obține d3.js și Backbone pentru a juca frumos împreună

În acest exemplu simplu, există cel puțin două soluții simple.

  1. Utilizați un selector CSS mai specific
  2. Utilizați o altă etichetă altfel

Cordonarea de pe o porțiune a DOM

Pentru exemple mai complicate, am putea avea nevoie de strategii alternative. O posibilă soluție este de a scoate o porțiune din DOM care va fi operată de una din biblioteci. De exemplu:

var CoolView = Backbone.View.extend (... renderVisualizare: functie (arrayOfData) d3.select ("# vizualizare") .selectAll ("p") .data (arrayOfData) .enter .text (funcția (d) retur "Sunt numărul" + d + "!");); var coolView = noul CoolView (); var myData = [10, 9, 4, 2, 1]; coolView.renderVisualization (MYDATA); 

În cazul de mai sus, Backbone continuă să gestioneze vizualizarea pentru a fi creată. Cu toate acestea, să presupunem că există un element undeva în DOM (în interiorul sau în afara DOM gestionate de vizualizarea Backbone) a cărui id este "vizualizare". Putem valorifica acest fapt prin definirea tuturor acestor manipulări DOM legate de D3 acestui element. Ca rezultat, toate metodele cu lanț d3, inclusiv .selectAll ( "p") și .append ( "p"), sunt executate în contextul #visualization.

Încapsulați manipularea DOM diferențiată cu subdiviziuni

În cele din urmă, o altă metodă de gestionare a funcționalității de vizualizare a terților este folosirea sub-vizuale. Iată cum ar putea arăta asta.

var CoolView = Backbone.View.extend (render: function () var subViewA = nou SubViewA (); var subViewB = nou SubViewB (); // setarea continutului html pentru coolview acest lucru $ el.html (subViewA.render () .el); / / adăugați mai mult conținut html pentru a vizualiza această imagine de tip $ el.append (subViewB.render (). // În altă parte, poate în ruterul dvs. ... var coolView = CoolView nou (); $ ( 'App') html (coolView.render () el.).; 

În acest scenariu, subViewA ar putea conține conținut de non-vizualizare și subViewB poate conține conținut de vizualizare.

O altă abordare comună de manipulare DOM pentru Backbone + d3.js

Există momente când trebuie să vă asigurați că manipularea DOM d3 are loc în același context cu vizualizarea din spate. De exemplu, pur și simplu delimitarea unei porțiuni din DOM cu #visualization nu oferă nicio garanție că elementul există în interiorul sau în afara părții din DOM reprezentată de vizualizarea Backbone.

O alternativă este să vă asigurați că selecția de pornire d3 se referă la același element ca cel indicat de acest lucru. $ el. Cu toate acestea, dacă nu aveți tendința să nu setați el sau oricare dintre atributele sale direct, ar fi dificil să vizați în mod suficient viziunea curentă utilizând CSS.

Din fericire, în biblioteca d3.js, există o metodă care permite selectarea nodului direct. Lasa-ma sa te prezint d3.select (nod). Conform documentației, această metodă:

Selectează nodul specificat. Acest lucru este util dacă aveți deja o referință la un nod, cum ar fi d3.select (acest lucru) în cadrul unui ascultător de evenimente sau un document global, cum ar fi document.body. Această funcție nu traversează DOM.

Această metodă ne permite să scriem codul următor și să ne asigurăm că manipulările d3 apar în contextul vizualizării Backbone.

var CoolView = Backbone.View.extend (// rețineți că "el" nu este setat direct rendering: function () var html = "

Nu sunt un număr!

", acest lucru se referă la un obiect Backbone d3.select (acest lucru); .el) // introduceți într-o referință de nod .selectAll ("p") .data (arrayOfData) .enter () .append ("p") .text (funcția (d) + "!"););

Concluzie

În rezumat, există o serie de considerente atunci când faceți Backbone să joace frumos cu alte manipulatoare DOM.

  1. Asigurați-vă că selectați elementul potrivit pentru a manipula. Folosind clase CSS specifice și ID-uri pot face viața mult mai ușoară.
  2. Folosirea inteligentă a diverselor metode de manipulare DOM în oricare dintre biblioteci poate merge mult. Asigurați-vă că ați clarificat acțiunea DOM (adăugați, prefixați, inserați, eliminați) de care aveți nevoie.
  3. Operațiunile cu buclă în DOM pot fi complicate. Asigurați-vă că elementele corecte sunt afectate.

Există, de asemenea, o serie de alternative de luat în considerare, în funcție de rezultatul dorit:

  1. Separarea unei porțiuni din DOM
  2. Direcționarea altei manipulări DOM a bibliotecii în contextul Backbone
  3. Utilizarea sub-vizualizări pentru a încapsula impactul altor manipulatoare DOM
Cod