I den siste artikkelen dekket vi grunnleggende om Backbone Views og hvordan du aktiverer jQuery for å manipulere det samme DOM som Backbone manipulerer sømløst.
I denne artikkelen vil vi undersøke hvordan vi kan gjøre Backbone spille pent med d3.js. Konseptene i denne artikkelen bør gjelde for situasjoner der du har tenkt å bruke Backbone med de fleste andre biblioteker som også manipulerer DOM.
d3.js, skrevet av Mike Bostock, er et annet mye brukt bibliotek som manipulerer Document Object Model, først og fremst for å visualisere data. Faktisk kan du bli veldig kreativ med måten dataene kan visualiseres på.
På det laveste nivået interagerer d3.js med HTML- og / eller SVG-elementer og manipulerer sine attributter ved å binde data til dokumentobjektmodellen.
Her er et raskt eksempel på hvordan d3 opererer:
var numericalData = [1,2,3,4,5,6]; d3.select ("body"). selectAll ("p") .data (numericalData) .enter () .append ("p") .text (funksjon (d) return "Jeg er nummer" + d + " ! ";);
Ovennevnte kode gjør følgende:
kropp
elementp
elementer som for øyeblikket er i DOMnumericalData
til en valgt p
elementp
element som har ennå ikke eksistert (dvs. noen elementer i numericalData
som fortsatt må legges til), skaper en p
element og legger til det DOMp
element for å inneholde litt tekst (inkludert det aktuelle nummeret i numericalData
)Å utnytte det vi lærte i forrige artikkel, er her en implementering av en delt DOM-manipulasjon.
var CoolView = Backbone.View.extend (render: function () var html = "Jeg er ikke et nummer!
"; dette. $ el.html (html); returner dette; renderVisualization: function (arrayOfData) d3.select (" body ") .selectAll (" p ") .data (arrayOfData) .enter () .append ("p") .text (funksjon (d) return "Jeg er nummer" + d + "!";;;); var coolView = ny CoolView (); coolView.render (); var myData = [10, 9, 4, 2, 1]; coolView.renderWithD3 (myData);
Forutsatt at vårt mål er å bevare det eksisterende p
element og legg til den andre p
elementer til DOM, når vi utfører ovennevnte kode, løper vi raskt inn i et stort problem.
De .render ()
innsatser en p
element med teksten "Jeg er ikke et nummer" i DOM. Men .renderVisualization ()
velger alle eksisterende p
elementer i DOM og legger inn innhold i disse elementene. Dette skriver teksten i originalen p
element, til tross for vår føye til DOM bruker d3.append ()
.
I dette enkle eksempel eksisterer det minst to enkle løsninger.
For mer kompliserte eksempler kan vi trenge alternative strategier. En potensiell løsning er å koble av en del av DOM som skal betjenes av ett av bibliotekene. For eksempel:
var CoolView = Backbone.View.extend (... renderVisualization: function (arrayOfData) d3.select ("# visualisering") .selectAll ("p") .data (arrayOfData) .enter () .append ("p") .text (funksjon (d) return "Jeg er nummer" + d + "!";);); var coolView = ny CoolView (); var myData = [10, 9, 4, 2, 1]; coolView.renderVisualization (mydata);
I det ovennevnte tilfellet fortsetter Backbone å administrere visningen som skal opprettes. Men la oss si at det er et element et sted i DOM (innsiden eller utenfor DOM som styres av ryggradssynet) hvis id er "visualisering". Vi kan kapitalisere på dette faktum ved å scoping alle våre d3-relaterte DOM manipulasjoner til dette elementet. Som et resultat, alle d3 kjedede metoder, inkludert .velger ( "p")
og .føyer ( "p")
, utføres i sammenheng med #visualization
.
Endelig er en annen tilnærming til å administrere tredjeparts visningsfunksjonalitet å bruke undervisninger. Her er hvordan det kan se ut.
var CoolView = Backbone.View.extend (render: function () var subViewA = ny SubViewA (); var subViewB = ny SubViewB (); // sett html innholdet for coolview dette. $ el.html (subViewA.render () .el); // legge til flere html-innhold for å se dette. $ el.append (subViewB.render (). el); returner dette;); // Andre steder, kanskje i ruteren din ... var coolView = ny CoolView (); $ ( 'App') html (coolView.render () el.).;
I dette scenariet, subViewA
kan inneholde ikke-visualiseringsinnhold, og subViewB
kan inneholde visualiseringsinnhold.
Det er tider når du må sørge for at d3 DOM-manipulasjonen din oppstår i samme kontekst som selve ryggraden. For eksempel kan du bare koble av en del av DOM med #visualization
gir ingen garanti for at elementet eksisterer innenfor eller utenfor delen av DOM som representeres av ryggraden.
Et alternativ er å sikre at ditt start-d3-utvalg refererer til det samme elementet som det som er pekt på dette. $ el
. Men hvis du har en tendens til ikke å sette el
eller noen av dens attributter direkte, ville det være vanskelig å målrette mot den nåværende visningen med CSS.
Heldigvis finnes det i d3.js-biblioteket en metode som gjør det mulig å velge direkte node. La meg introdusere deg til d3.select (node)
. Ifølge dokumentasjonen, denne metoden:
Velger den angitte noden. Dette er nyttig hvis du allerede har en referanse til en node, for eksempel d3.select (dette) innen en hendelselytter eller en global som document.body. Denne funksjonen går ikke gjennom DOM.
Denne metoden tillater oss å skrive følgende kode og sikre at d3-manipulasjoner forekommer i sammenheng med ryggradssyn.
var CoolView = Backbone.View.extend (// merk at "el" ikke er satt direkte gjengitt: funksjon () var html = "Jeg er ikke et nummer!
"; dette. $ el.html (html); return dette;, renderVisualization: function (arrayOfData) d3.select (this); // vil ikke fungere," dette "refererer til en ryggradobjekt d3.select .el) // pass i en noden referanse .selectAll ("p") .data (arrayOfData) .enter () .append ("p") .text (funksjon (d) return "Jeg er nummer" + d + "!";););
I sammendraget er det en rekke hensyn når Backbone spiller fint med andre DOM-manipulatorer.
Det er også en rekke alternativer å vurdere, avhengig av utfallet du søker: