Top 8 cele mai frecvente greșeli pe care le fac dezvoltatorii Backbone.js
Publicat: 2022-03-11Backbone.js este un cadru minimalist care își propune să ofere un set simplu de structuri de date și caracteristici pe care le puteți utiliza pentru a crea front-end-ul unei aplicații web structurate. Din cutie, componentele Backbone.js oferă un mediu intuitiv cu care este posibil să fiți deja familiarizat atunci când lucrați cu modele și vizualizări pe back-end. Modelele și colecțiile din Backbone.js sunt simple, dar vin cu câteva caracteristici foarte utile, cum ar fi opțiunea de a le integra cu ușurință cu API-urile REST JSON. Dar sunt și suficient de flexibile pentru a fi adaptate la aproape orice utilizare practică.
În acest tutorial Backbone.js, vom arunca o privire asupra unor greșeli obișnuite care sunt adesea făcute de dezvoltatorii independenți care fac prima încercare de a învăța Backbone.js și modalități de a le evita.
Greșeala nr. 1: Ignorarea Arsenalului de funcționalități Backbone.js
Backbone.js poate fi un cadru minimalist, dar (împreună cu Underscore.js) oferă o multitudine de caracteristici și funcționalități care pot acoperi cu ușurință cele mai de bază și unele dintre nevoile critice care apar la dezvoltarea unei aplicații web moderne. O greșeală comună pe care o fac adesea dezvoltatorii începători este aceea că iau Backbone.js ca fiind încă un cadru client asemănător MVC pentru web. Deși această secțiune vorbește despre ceva foarte evident, atunci când vine vorba de Backbone.js, este o greșeală cu adevărat critică să nu explorezi temeinic cadrul. Cadrul poate fi de dimensiuni mici, dar acesta este ceea ce îl face un candidat excelent pentru această explorare amănunțită. Mai ales codul sursă mic și frumos adnotat.
Backbone.js oferă minimul necesar pentru a oferi aplicației dvs. web structura de care poate beneficia. Cu extensibilitatea și multitudinea de pluginuri, învățarea Backbone.js poate fi folosită pentru a construi niște aplicații web uimitoare. Unele dintre cele mai evidente caracteristici ale Backbone.js sunt expuse prin modele, colecții și vizualizări. Componentele routerului și istoricului oferă un mecanism simplu, dar elegant pentru a sprijini rutarea pe partea clientului. Deși Underscore.js este o dependență de Backbone.js, este destul de bine integrat în cadru, deoarece modelele și colecțiile beneficiază atât de mult de această uimitoare centură de utilitate pentru JavaScript și este, de asemenea, disponibilă la dispoziția dumneavoastră.
Codul sursă al cadrului este atât de bine scris și adnotat încât probabil că s-ar putea citi totul în timp ce bei o ceașcă de cafea. Începătorii pot beneficia foarte mult de citirea adnotărilor sursă, deoarece pot afla multe despre cum funcționează cadrul intern și, de asemenea, pot adopta un set de bune practici atunci când vine vorba de JavaScript.
Greșeala nr. 2: modificarea DOM ca răspuns direct la evenimente arbitrare
Ceea ce avem tendința de a face atunci când începem să învățăm Backbone.js este să nu facem lucrurile așa cum ne recomandă Backbone.js. De exemplu, avem tendința să gestionăm evenimentele și să vedem actualizările așa cum am face-o cu jQuery pe site-uri simple. Backbone.js este destinat să ofere aplicației dvs. web o structură rigidă printr-o separare adecvată a preocupărilor. Ceea ce avem adesea tendința de a face cu Backbone.js este să actualizăm o vizualizare ca răspuns la evenimente DOM arbitrare:
var AudioPlayerControls = Backbone.View.extend({ events: { 'click .btn-play, .btn-pause': function(event) { $(event.target).toggleClass('btn-play btn-pause') } }, // ... })
Acesta este ceva ce ar trebui evitat cu orice preț. Este posibil să venim cu exemple obscure în care acest lucru poate avea sens; dar în cele mai multe cazuri, există modalități mult mai bune de a face acest lucru. De fapt, un mod pe care l-aș putea exemplifica aici este să folosesc modelul pentru a urmări starea playerului audio și să folosesc acele informații despre stare pentru a reda butonul (sau mai precis numele clasei sale):
var AudioPlayerControls = Backbone.View.extend({ events: { 'click .btn-play, .btn-pause': function(event) { this.model.set('playing', !this.model.get('playing')) } }, initialize: function() { this.listenTo(this.model, 'change', this.render) this.render() }, // ... })
<button class=”btn btn-<%- playing ? 'pause' : 'play' %>”></button>
Pot exista situații rare în care manipularea directă a DOM de la gestionanții de evenimente va avea sens, dar costul implicat cu gestionarea manipulărilor complexe DOM de la gestionatorii de evenimente nu merită aproape niciodată. Acesta este ceva ce Backbone.js își propune să rezolve. A folosi Backbone.js pentru a face așa ceva este o greșeală.
Greșeala nr. 3: Subestimarea costului randării
Întrucât Backbone.js face foarte ușor să randați și să redați din nou DOM-ul după bunul plac sau ca răspuns la evenimente, de multe ori trecem cu vederea cât de mult impact are acest lucru asupra performanței generale a aplicației web. Există multe modalități în care putem ajunge să depășim metoda de randare a vizualizărilor noastre. Adesea, acest lucru poate să nu pară prea mult, deoarece browserele web moderne devin piese de software foarte performante. Dar pe măsură ce aplicația web crește și cantitatea de date cu care se ocupă crește, scăderea performanței devine din ce în ce mai evidentă.
Putem vedea acest lucru în acțiune printr-un exemplu artificial în care începem cu o mică colecție de modele și le redăm într-o vizualizare de listă:
var AudioPlayerPlaylist = Backbone.View.extend({ template: _.template('<ul> <% _.each(musics, function(m) { %> <li><%- m.title %></li> <% }) %> </ul>'), initialize: function() { this.listenTo(this.collection, 'add', this.render) }, // ... })
În acest exemplu Backbone.js, redăm din nou ori de câte ori un model este adăugat la colecție. Acest lucru va funcționa bine. Cu toate acestea, deoarece evenimentul „adăugați” este declanșat de fiecare dată când un model este adăugat la listă, imaginați-vă că puteți prelua o listă mare de modele de pe server. Metoda de randare va fi invocată de mai multe ori consecutiv, o dată pentru fiecare model din răspunsul de la server. Un model suficient de mare va fi suficient pentru a face aplicația să se bâlbâie și să strice experiența utilizatorului. Uneori, un răspuns mic este suficient, în funcție de complexitatea vizualizării redate.
O soluție foarte rapidă este să nu apelați metoda de randare pentru fiecare model care este adăugat. În situații ca acestea, modelele vor fi adăugate în lot și puteți face ceva pentru ca metoda de randare să se declanșeze numai atunci când este invocată, dar nu reinvocată într-un interval de timp specificat. Dependența lui Backbone.js Underscore.js vine cu o funcție de utilitate la îndemână pentru aceasta: „_.debounce”. Tot ce aveți nevoie pentru a profita de acest lucru este să schimbați linia JavaScript de legare a evenimentelor cu aceasta:
this.listenTo(this.collection, 'add', _.debounce(_.bind(this.render), 128))
Acest lucru va face ca apelarea evenimentului să fie declanșată de fiecare dată când are loc evenimentul „adăugați”, cu toate acestea, va aștepta 128 de milisecunde de la ultimul eveniment înainte de a invoca efectiv metoda de randare.
În cele mai multe cazuri, aceasta va fi considerată o soluție asemănătoare cu remedierea rapidă. De fapt, există modalități mai adecvate de a evita redarea thrashing. Dezvoltatorii din spatele Trello au scris odată o postare pe blog în care discutau despre experiența și abordarea lor în îmbunătățirea performanței de randare în timp ce folosesc Backbone.js.
Greșeala nr. 4: Lăsând ascultătorii evenimentelor legați dincolo de utilizarea lor
Lăsarea ascultătorilor de evenimente neutilizați este probabil ceva care se poate întâmpla indiferent de cadru JavaScript pe care îl utilizați sau dacă folosiți unul. Chiar dacă Backbone.js ușurează evitarea acestei probleme, este cu siguranță o greșeală să lăsați posibile găuri pentru scurgeri ușoare de memorie în aplicația dvs. web. Componenta „Eveniment” a Backbone.js este cu siguranță o implementare destul de bună. Permite obiectelor JavaScript să implementeze cu ușurință caracteristici bazate pe evenimente. Deoarece vizionările sunt locul unde se întâmplă de obicei cea mai mare parte a consumului de evenimente, este ușor să facem această greșeală acolo:
var AudioPlayerControl = Backbone.View.extend({ initialize: function() { this.model.on('change', _.bind(this.render, this)) // ... }, // ... })
Linia de legare a evenimentelor din acest fragment de cod nu este foarte diferită de cea din primul exemplu. Tot ce am făcut aici este că am schimbat „this.listenTo(this.model, …)” în „this.model.on(…)”. Deoarece suntem foarte obișnuiți cu apelul „.on()” pentru legarea de evenimente din experiența noastră cu alte cadre și biblioteci JavaScript, atunci când începem să folosim Backbone.js, avem adesea tendința de a folosi apelurile „.on()” pentru a lega. evenimente. Acest lucru ar fi fost bine, doar dacă ne-am deranjat să apelăm „.off()” pentru a dezlega gestionatorii de evenimente atunci când nu mai sunt necesari. Dar rareori facem asta și ajunge să fie o sursă de scurgeri de memorie.

Backbone.js oferă o modalitate simplă de a rezolva această problemă. Este prin utilizarea metodei „object.listenTo()”. Acest lucru permite obiectului pe care îl apelați „listenTo()” să țină evidența evenimentelor pe care le ascultă și, de asemenea, ușurează deconectarea tuturor acestor evenimente simultan. Vizualizările, de exemplu, opresc automat ascultarea tuturor evenimentelor legate de îndată ce apelați „remove()” pe el.
Greșeala #5: Crearea vederilor monolitice
Dacă vă gândiți bine, minimalismul lui Backbone.js oferă o mare flexibilitate modului în care doriți să proiectați front-end-ul aplicației dvs. web. Având în vedere că modelele, colecțiile și vederile sunt elementele de bază ale componentelor dvs., este esențial să le păstrați cât mai ușoare și cât mai specifice posibil. De cele mai multe ori, vizualizările ajung să devină cel mai greu aspect al aplicației tale web în ceea ce privește codul. Dar este foarte important să nu ajungi să faci vederi monolitice uriașe care ajung să încerce să facă tot ce are de oferit aplicația ta. În loc să creați o vizualizare uriașă „AudioPlayer” cu toată logica înghesuită în ea, împărțiți-o într-un număr de vizualizări logice, cum ar fi o vizualizare pentru lista de redare, o vizualizare pentru comenzi, o vizualizare pentru vizualizator și așa mai departe. Ce fel de granularitate doriți să vă asigurați depinde probabil de aplicația pe care încercați să o construiți.
Acest lucru se datorează faptului că, cu vizualizări granulare, în care fiecare vizualizare face ceva specific și face bine, dezvoltarea unei aplicații web cu Backbone.js devine o briză. Codul dvs. ar trebui să fie mai ușor de întreținut și mai ușor de extins sau modificat în viitor. Apoi este cealaltă extremă, în care ajungi să exagerezi. Vizualizările Backbone.js sunt concepute astfel încât să vă fie convenabil să lucrați cu un model sau o colecție, iar acest lucru poate funcționa probabil ca un indiciu pentru modul în care ar trebui să vă structurați aplicația. Ian Storm Taylor a împărtășit câteva idei valoroase pe blogul său de care probabil ar trebui să le țineți cont atunci când implementați vizualizări.
Greșeala nr. 6: Nu realizați că Backbone.js poate fi adaptat la API-uri care nu sunt RESTful
Backbone.js funcționează cu API-uri RESTful bazate pe JSON. Tot ce aveți nevoie pentru asta este jQuery (sau ceva care să fie un înlocuitor pentru acesta, cum ar fi Zepto). Cu toate acestea, Backbone.js este extrem de extensibil. De fapt, Backbone.js poate fi adaptat pentru a utiliza chiar și alte tipuri de API-uri și alte tipuri de formate de codare.
Componenta Backbone.js care se ocupă de interacțiunea front-end-ului cu serviciile back-end este „Sync”. Această componentă expune o serie de atribute pe care le puteți suprascrie cu ușurință pentru a personaliza modul Backbone.js de a interacționa cu punctele finale API. De fapt, este, de asemenea, posibil să înlocuiți mecanismul de sincronizare implicit cu ceva care nu este atât de tradițional, cum ar fi utilizarea localStorage pentru a persista datele, în loc de servicii back-end.
Există numeroase pluginuri care facilitează personalizarea comportamentului de sincronizare al lui Backbone.js. De exemplu, un plugin numit Backbone.dualStorage vă permite să utilizați atât serviciile back-end, cât și localStorage pentru a persista datele. Când aplicația dvs. este offline, pluginul folosește localStorage pentru a continua să servească cererile din datele stocate în cache și pentru a urmări modificările pe care le puteți sincroniza cu serverul mai târziu, când sunteți online.
Deși utilizarea Backbone.js cu un back-end care este proiectat să fie RESTful și compatibil cu acesta este mai ușor de utilizat, aceasta nu înseamnă că este tot ce poate funcționa Backbone.js. Cu unele modificări ale mecanismului de sincronizare implicit Backbone.js, îl puteți adapta la o gamă largă de API-uri și formate de codare de servicii back-end.
Merită menționat faptul că și alte părți ale Backbone.js sunt flexibile și, în anumite moduri, opționale. De exemplu, nu trebuie să utilizați motorul implicit de șabloane care vine cu Underscore.js. Nici măcar nu trebuie să utilizați componenta de vizualizare a Backbone.js și o puteți înlocui cu altceva dacă doriți.
Greșeala nr. 7: Stocarea datelor pe vizualizări, nu în modele
O greșeală pe care o facem adesea ca începători care învață Backbone.js este stocarea datelor direct pe vizualizări ca atribute. Aceste date pot fi acolo pentru a urmări o anumită stare sau o anumită selecție de utilizator. Acesta este ceva ce ar trebui evitat.
var AudioPlayerVisualizer = Backbone.View.extend({ events: { 'click .btn-color': function(event) { this.colorHex = $(event.target).data('color-hex') this.render() } }, // ... })
Puteți crea oricând câteva modele și colecții suplimentare fără puncte finale. Acestea vă pot ajuta să stocați date care nu trebuie neapărat să fie menținute în back-end sau care pot fi de natură temporară. Stocarea lor în modele vă oferă avantajul de a putea asculta modificările. Vederea relevantă, sau chiar mai multe vizualizări, pot observa aceste modele și se pot reda după caz.
Imaginați-vă dacă ați stocat de fapt variabile de urmărire a stării pe vizualizări și ar trebui să apelați metoda de randare de fiecare dată când le-ați schimbat. Lipsa unui singur apel la această metodă de randare ar putea lăsa aplicația dvs. într-o stare defectă, în ceea ce privește ceea ce experimentează utilizatorul pe ecran. Mai mult, cu vederi mici, este posibil să trebuiască să sincronizați aceste variabile de stare pe mai multe obiecte de vizualizare și apoi să apelați și pe ele metoda de randare.
Greșeala #8: Folosirea jQuery „.on()” în loc de evenimente delegate
Backbone.js are, în opinia mea, o modalitate magnifică de a gestiona evenimentele DOM. Nefolosirea acestuia prezintă o grămadă de dezavantaje. Funcția de legare a evenimentelor „.on()” a jQuery poate fi convenabilă, dar deseori se dovedește a fi o problemă pe termen lung. De exemplu, atunci când elementele sunt detașate din DOM, jQuery elimină automat toți gestionanții de evenimente legați de elemente folosind „.on()”. Aceasta înseamnă că orice eveniment DOM la care încercați să vă legați dintr-o vizualizare va trebui să fie rebound dacă detașați elementul rădăcină din DOM și îl atașați din nou.
var AudioPlayerControls = Backbone.View.extend({ events: { 'click .btn-play, .btn-pause': function() { /* ... */ }, 'click .btn-prev': function() { /* ... */ }, 'click .btn-next': function() { /* ... */ }, 'click .btn-shuffle': function() { /* ... */ }, 'click .btn-repeat': function() { /* ... */ } }, // ... })
Când elementul corespunzător acestei vederi este re-atașat la DOM, tot ce trebuie să faceți este să apelați „delegateEvents()” pe vizualizare pentru a lega toate aceste evenimente.
Rețineți că este important să înțelegeți cum sunt legate aceste evenimente. În loc să lege evenimentul de elementele specificate de selector, Backbone.js leagă de fapt handlerul de evenimente la elementul rădăcină al vizualizării. Acest lucru funcționează bine în aproape toate cazurile și, de fapt, funcționează mai bine pentru majoritatea nevoilor noastre. Schimbarea sau înlocuirea elementelor secundare din subarborele DOM al vizualizării nu necesită ca Backbone.js să lege fiecare eveniment din nou la elementele noi. Ascultătorii existenți continuă să lucreze.
Cu toate acestea, acest lucru împiedică ascultarea anumitor evenimente. Un exemplu este cazul în care ați putea dori să ascultați evenimente de defilare pe „fereastră” sau pe un element derulabil copil. În cazul elementelor copil, puteți face o sub-vizualizare pentru acel element și puteți gestiona evenimentele de acolo.
Concluzie
Backbone.js, fiind un cadru foarte compact, dar extensibil, este o alegere excelentă pentru aplicațiile web care necesită multă flexibilitate în spatele scenei. Spre deosebire de cadre precum Angular.js și Ember.js, care sunt întotdeauna acolo pentru a vă spune cum să faceți ceea ce doriți să faceți, Backbone.js face un pas înapoi, vă oferă un set puternic de instrumente și vă permite să decideți cum să utilizați lor. Sper că acest tutorial Backbone.js pentru începători vă va ajuta să evitați unele dintre greșelile comune de dezvoltare și să construiți ceva uimitor cu el.