Utilizați Backbone.js pentru a accelera interacțiunile

Autor: Monica Porter
Data Creației: 13 Martie 2021
Data Actualizării: 15 Mai 2024
Anonim
Scaling Backbone.js at SoundCloud
Video: Scaling Backbone.js at SoundCloud

Conţinut

Dacă doriți să construiți rapid un mic instrument JavaScript, probabil că nu vă gândiți să folosiți un cadru. Mai ușor să hack împreună un cod jQuery, mai degrabă decât să instalați și să învățați un nou cadru, nu? Greșit, Backbone.js este un cadru de lipici foarte ușor, care arată la fel ca vechiul JavaScript obișnuit pe care îl obișnuiești să scrii.

Aici facem o mulțime de prototipuri statice la ZURB, pentru că ne place să putem face clic pe pagini fără a fi nevoie să scriem niciun cod de backend. Adesea, aruncăm imagini substituente gri, sau uneori căutam în Flickr exemple de imagini care să ne ajute să vizualizăm ce ar putea merge în schița finală. Asta până într-o vineri magică, când am decis că ar fi minunat să scriem ceva JavaScript pentru a ne rezolva problemele. Am vrut să putem căuta și selecta fotografii pe Flickr, direct din imaginile substituente. L-am numi FlickrBomb și aceasta este povestea modului în care am construit-o folosind Backbone.js.


Este foarte recomandat să aruncați o privire rapidă la FlickrBomb înainte de a citi. Este una dintre acele tipuri de oferte „un clic merită o mie de cuvinte”. Continuați, vom aștepta.

În zilele noastre există o mulțime de cadre JavaScript, SproutCore, JavaScriptMVC, Spine, Sammy, Knockout. Dar ne-a plăcut Backbone.js pentru acest proiect special din câteva motive diferite:

1. Este ușor (de fapt 100% fără grăsimi)

  • în greutate, cea mai recentă versiune ambalată fiind de aproximativ 4,6 kb
  • în cod, fiind puțin peste 1.000 de linii de cod, nu este teribil de greu să urmărești o urmă de stivă în interior, fără a-ți pierde mintea

2. Arată ca JavaScript

  • pentru că este JavaScript, asta este și atât
  • folosește jQuery, pe care chiar și bunica ta îl cunoaște în zilele noastre

3. Persistență super simplă


  • din cutie persistă datele într-un backend (prin REST), dar prin introducerea unui singur plug-in se va salva în loc de stocare locală
  • deoarece abstractizează API-ul de persistență, am putea să îl menținem într-un backend REST, eliminând doar plug-in-ul de stocare locală

Să începem atunci

Deoarece Backbone.js este doar JavaScript, tot ce trebuie să facem este să îl includem împreună cu Underscore.js pe pagină. jQuery nu este o dependență dificilă pentru Backbone în sine, dar îl vom folosi, așa că îl vom include aici. De asemenea, vom conecta plug-in-ul de stocare locală, deoarece nu vrem să ne facem probleme cu configurarea unui backend. Rețineți că au fost conectate direct fișierele aici pentru simplitate, dar ar trebui să găzduiți întotdeauna propriile active în producție.

script src = "http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"> / script> script src = "http://documentcloud.github.com/backbone/ backbone-min.js "> / script> script src =" http://documentcloud.github.com/underscore/underscore-min.js "> / script> script src =" https://raw.github.com/ jeromegn / Backbone.localStorage / master / backbone.localStorage-min.js "> / script>

Toate următoarele coduri din acest articol sunt specifice aplicației noastre, așa că îl putem include într-un fișier app.js sau doar în linie, dacă asta vă aparține. Nu uitați să îl includeți după Backbone. Backbone permite să extragem porțiuni din aplicația noastră, pentru a le face atât modulare pentru o reutilizare ușoară, cât și mai ușor de citit pentru alții. Pentru a ilustra cel mai bine acea abstracție, aveam să explicăm designul FlickrBomb de jos în sus, începând cu modelele și terminând cu vederile.


Primul nostru model

Prima sarcină pe care urmau să o abordeze este extragerea fotografiilor de la Flickr. Modelarea unui FlickrImage în coloana vertebrală este suficient de simplă, vom crea un nou model numit FlickrImage și vom adăuga câteva metode care să ne ajute să obținem dimensiuni diferite.

var FlickrImage = Backbone.Model.extend ({fullsize_url: function () {return this.image_url ('medium');}, thumb_url: function () {return this.image_url ('square');}, image_url: function ( size) {var size_code; switch (size) {case 'square': size_code = '_s'; break; // 75x75 case 'medium': size_code = '_z'; break; // 640 pe cea mai lungă carcasă laterală 'large ': size_code =' _b '; break; // 1024 pe partea cea mai lungă implicită: size_code =' ';} returnează "http: // farm" + this.get (' farm ') + ".static.flickr.com / "+ this.get ('server') +" / "+ this.get ('id') +" _ "+ this.get ('secret') + size_code +" .webp ";}})

Modelele din Backbone sunt obiecte care pot fi persistate și au unele funcții asociate acestora, la fel ca modelele din alte cadre MVC. Partea magică a modelelor Backbone este că putem lega evenimentele de atribute, astfel încât, atunci când acel atribut se schimbă, să ne putem actualiza opiniile pentru a reflecta acest lucru. Dar ne depășim puțin.

Când extragem fotografiile din Flickr, vom obține suficiente informații pentru a crea adrese URL pentru toate dimensiunile. Cu toate acestea, acel ansamblu ne este lăsat la latitudinea noastră, așa că am implementat funcția .image_url () care ia un parametru de dimensiune și returnează un link public. Deoarece acesta este un model de bază, putem folosi this.get () pentru a accesa atributele modelului. Deci, cu acest model, putem face următoarele în altă parte a codului pentru a obține adresa URL a unei imagini Flickr.

flickrImage.image_url („mare”)

Destul de concis, nu? Întrucât acest model este specific aplicației noastre, vom adăuga câteva funcții de împachetare pentru dimensiunile de dimensiuni mari și de dimensiuni mari ale imaginii.

O colecție de imagini

FlickrBomb se ocupă de colecții de imagini, nu de imagini unice, iar Backbone are un mod convenabil de a modela acest lucru. Colecția numită în mod adecvat este ceea ce vom folosi pentru a grupa imaginile Flickr împreună pentru un singur substituent.

var FlickrImages = Backbone.Collection.extend ({model: FlickrImage, cheie: flickrbombAPIkey, pagina: 1, preluare: funcție (cuvinte cheie, succes) {var self = this; success = success || $ .noop; this.keywords = keywords || this.keywords; $ .ajax ({url: 'http://api.flickr.com/services/rest/', date: {api_key: self.key, format: 'json', metodă: 'flickr. photos.search ', etichete: this.keywords, per_page: 9, page: this.page, licență: flickrbombLicenseTypes}, dataType:' jsonp ', jsonp:' jsoncallback ', succes: funcție (răspuns) {self.add (răspuns .photos.photo); success ();}});}, nextPage: funcție (callback) {this.page + = 1; this.remove (this.models); this.fetch (nul, callback);}, prevPage: function (callback) {if (this.page> 1) {this.page - = 1;} this.remove (this.models); this.fetch (nul, callback);}});

Există câteva lucruri de remarcat aici. În primul rând, model atributul le spune colecțiilor ce tip de model colectează. De asemenea, avem câteva atribute pe care le-am inițializat pentru a fi utilizate ulterior: cheia este cheia API Flickr, veți dori să înlocuiți flickrbombAPIkey cu șirul propriei chei API Flickr. Obținerea unei chei API Flickr este gratuită și ușoară, trebuie doar să urmați acest link: www.flickr.com/services/api/misc.api_keys.html. Atributul de pagină este pagina curentă a fotografiilor Flickr pe care ne aflăm.

Marea metodă aici este .fetch (), care abstractizează detaliile despre extragerea fotografiilor din API-ul Flickr. Pentru a evita problemele cu solicitările pe mai multe domenii, folosim JSONP, pe care îl acceptă atât API-ul Flickr, cât și jQuery. Ceilalți parametri pe care îi trecem către API ar trebui să fie auto-explicativi. De un interes special sunt numite aici funcțiile Backbone. În callback-ul de succes, folosim .add (), o funcție care ia o serie de atribute de model, creează instanțe de model din acele atribute și apoi le adaugă la colecție.

Funcțiile .nextPage () și .prevPage () modifică mai întâi pagina pe care dorim să o afișăm,
utilizați funcția de colectare .remove (), pentru a elimina toate modelele existente din
colecție, apoi apelați la fetch pentru a obține fotografiile pentru pagina curentă (pe care tocmai le-am făcut
schimbat).

FlickrBombImage

Făcând drumul înapoi, avem nevoie de încă un model pentru a reprezenta imaginea substituent, care va consta dintr-o colecție de imagini Flickr și FlickrImage curentă care a fost selectată. Vom numi acest model FlickrBombImage.

var localStorage = (supports_local_storage ())? new Store ("flickrBombImages"): null; var FlickrBombImage = Backbone.Model.extend ({localStorage: localStorage, initialize: function () {_.bindAll (this, 'loadFirstImage'); this.flickrImages = new FlickrImages (); this.flickrImages.fetch (this.get ('cuvinte cheie'), this.loadFirstImage); this.set (id: this.get ("id")); this.bind ('change: src', this.changeSrc) ;}, changeSrc: function () {this.save ();}, loadFirstImage: function () {if (this.get ('src') === nedefinit) {this.set ({src: this.flickrImages. first (). image_url ()});}}});

Deoarece acest model este responsabil pentru urmărirea imaginii selectate în prezent între încărcările paginii, trebuie să știe ce magazin de stocare local să utilizeze.Prima linie se va asigura că există suport pentru stocarea locală și apoi va crea magazinul pe care îl vom folosi pentru a persista imaginea selectată.

Backbone ne permite să definim o funcție .initialize () care va fi apelată când se creează o instanță a modelului. Folosim această funcție în FlickrBombImage pentru a crea o nouă instanță a colecției FlickrImages, pentru a trece de-a lungul cuvintelor cheie care vor fi folosite pentru această imagine, apoi pentru a prelua imaginile din Flickr.

Funcția .loadFirstImage () a fost transmisă ca callback pentru a rula atunci când imaginile au fost încărcate de la Flickr. După cum probabil puteți ghici, această funcție setează imaginea curentă să fie prima din colecția de la Flickr. Nu face acest lucru dacă imaginea curentă a fost deja setată.

De asemenea, vom folosi apelurile de apelare ale atributelor Backbone pentru a declanșa funcția noastră .changeSrc () atunci când se schimbă atributul src al acestui model. Tot ceea ce face acest apel invers este call .save (), o funcție de model Backbone care persistă atributele modelului oricărui strat de magazin care a fost implementat (în cazul nostru localstore). În acest fel, ori de câte ori imaginea selectată este modificată, aceasta este persistată imediat.

Stratul de vizualizare

Acum, că avem tot codul backend (bine, backend) scris, putem pune împreună Vizualizările. Vizualizările din Backbone sunt puțin diferite de cele din alte cadre tradiționale MVC. În timp ce o vizualizare se referă de obicei la prezentare, o vizualizare Backbone este responsabilă și pentru comportament. Asta înseamnă că Vizualizarea dvs. nu numai că definește aspectul ceva, ci și ce ar trebui să facă atunci când interacționați.

O vizualizare este legată în mod obișnuit (dar nu întotdeauna) de unele date și trece prin trei faze pentru a genera marcaje de prezentare din aceste date:

1. Obiectul View este inițializat și se creează un element gol.
2. Se apelează funcția de redare, generând marcajul pentru vizualizare inserându-l în elementul creat în pasul anterior.
3. Elementul este atașat la DOM.

Acest lucru poate părea o mulțime de muncă pentru a genera o oarecare marcare și nici măcar nu suntem încă la partea de comportament a vizualizării, dar este importantă și iată de ce. De fiecare dată când modificați elemente care se află în DOM, declanșați ceva numit reflow al browserului. Un reflow este browserul care recalculează modul în care este poziționat fiecare lucru de pe pagină. Redirecționările browserului pot fi dăunătoare pentru performanță dacă sunt apelate într-un eveniment de tragere sau redimensionare, care se declanșează la un interval foarte scurt, dar, mai rău, ele arată neglijent. Cu manipularea complexă a paginii, puteți vedea de fapt elemente adăugate la pagină și repoziționarea elementelor efectuate. Urmând modelul de inițializare, redare și atașare al Backbone, veți garanta o singură refluxare, iar modificările paginii vor fi perceptiv instantanee, indiferent de complexitatea manipulării elementelor.

FlickrBombImageView

var FlickrBombImageView = Backbone.View.extend ({tagName: "div", className: "flickrbombContainer", lock: false, template: _.template ('div id = "% = this.image.id.replace (" ", "")%> "... / div> '), initialize: function (options) {_.bindAll (this,' addImage ',' updateSrc ',' setDimentions ',' updateDimentions '); var keywords = options. img.attr ('src') .replace ('flickr: //', ''); this. $ el = $ (this.el); this.image = new FlickrBombImage ({keywords: keywords, id: options. img.attr ('id')}); this.image.flickrImages.bind ('add', this.addImage); this.image.bind ('change: src', this.updateSrc);}, evenimente: { "click .setupIcon": "clickSetup", "click .flickrbombFlyout a.photo": "selectImage", "click .flickrbombFlyout a.next": "nextFlickrPhotos", "click .flickrbombFlyout a.prev": "prevFlickrPhotos"}, render: function () {$ (this.el) .html (this.template ()); this.image.fetch (); this.resize (); return this;}, ...});

Funcțiile acestei vizualizări au fost omise pentru concizie, codul sursă în întregime este disponibil pe GitHub: github.com/zurb/flickrbomb

În partea de sus a Vizualizării, avem câteva atribute specifice Backbone. tagName și className sunt folosite pentru a defini eticheta și clasa care vor fi aplicate elementului acestei vizualizări. Amintiți-vă că primul pas din crearea vizualizării este crearea unui obiect și, deoarece această creație este gestionată de Backbone, trebuie să specificăm elementul și clasa. Rețineți că Backbone are valori implicite sensibile; dacă omitem aceste atribute, se utilizează în mod implicit un div și nu se va aplica nicio clasă decât dacă specificați una.

Atributul șablon este o convenție, dar nu este necesar. Îl folosim aici pentru a specifica funcția șablon JavaScript pe care o vom folosi pentru a genera marcajul nostru pentru această vizualizare. Folosim funcția _.template () inclusă în Underscore.js, dar puteți folosi motorul de modelare pe care îl preferați, nu vă vom judeca.

În funcția noastră .initialize () scoatem șirul de cuvinte cheie din eticheta imagine și apoi creăm un model FlickrBombImage folosind acele cuvinte cheie. De asemenea, legăm funcția .addImage () pentru a fi executată atunci când se adaugă un FlickrImage la colecția FlickrImages. Această funcție va adăuga noul FlickrImage adăugat la meniul nostru selectiv de imagine. Ultima și cea mai importantă linie este legarea funcției .updateSrc () să se declanșeze atunci când FlickrImage selectată în prezent este modificată. Când imaginea curentă este modificată în model, această funcție va rula, actualizează atributul src al elementului de imagine și CSS redimensionează și decupează imaginea pentru a se încadra în dimensiunile imaginii specificate de utilizator.

events: {"click .setupIcon": "clickSetup", "click .flickrbombFlyout a.photo": "selectImage", "click .flickrbombFlyout a.next": "nextFlickrPhotos", "click .flickrbombFlyout a.prev": "prevFlickrPhotos "}

După .initialize () avem porțiunea de comportament a Vizualizării. Backbone oferă un mod convenabil de a lega evenimentele folosind un obiect de evenimente. Obiectul evenimente folosește metoda jQuery .delegate () pentru a efectua legarea efectivă la elementul Vizualizare, astfel încât, indiferent de ce manipulare faceți elementului din vizualizare, toate evenimentele legate vor funcționa în continuare. Funcționează la fel ca jQuery .live (), cu excepția faptului că, în loc să legați evenimentele la întregul document, le puteți lega în cadrul oricărui element. Cheia fiecărei intrări din obiectul evenimente constă din eveniment și selector, valoarea indică acea funcție care ar trebui să fie legată de acel eveniment. Rețineți că .delegate () nu funcționează cu anumite evenimente, cum ar fi trimitere, consultați documentația jQuery .live () pentru o listă completă a evenimentelor acceptate.

render: function () {$ (this.el) .html (this.template ()); this.image.fetch (); this.resize (); returnează acest lucru;}

În cele din urmă, avem funcția .render () care este responsabilă pentru crearea marcajului nostru și pentru a face orice lucru suplimentar care nu poate fi efectuat până când marcajul Vizualizare nu a fost adăugat la elementul Vizualizare. După ce ne redăm șablonul, trebuie să apelăm .fetch () pe FlickrBombImage. .fetch () este o funcție Backbone care obține cea mai recentă copie a modelului din stratul de persistență. Dacă am fi salvat acest model înainte, .fetch () ar prelua acele date acum. După preluarea imaginii, trebuie să apelăm la redimensionare pentru a o poziționa corect.

Intinderea acasă

Cu toate piesele la locul lor, tot ce trebuie să facem acum este să găsim imaginile de substituent pe pagină și să le înlocuim cu vizualizările FlickrBombImage redate.

$ ("img [src ^ = 'flickr: //']") .each (funcție () {var img = $ (this), flickrBombImageView = new FlickrBombImageView ({img: img}); img.replaceWith (flickrBombImageView. render (). el);});

Acest mic fragment trebuie rulat în partea de jos a paginii sau într-un apel de apel pregătit pentru documente, pentru a se asigura că poate găsi imaginile substituente pe care le va înlocui. Folosim convenția de a specifica flickr: // [KEYWORD] în atributul src al unei etichete de imagine pentru a indica că ar trebui să fie populat cu imagini de la Flickr. Găsim elemente de imagine cu un atribut src potrivit, creăm un nou FlickrBombImageView și apoi înlocuim imaginea cu a noastră. Prindem o copie a imaginii originale și o transmitem FlickrBombView, astfel încât să putem extrage câteva opțiuni de configurare suplimentare care ar fi putut fi specificate pe element.

Rezultatul final al acestei munci este un API foarte simplu pentru persoanele care utilizează biblioteca. Aceștia pot defini pur și simplu etichete de imagine folosind convenția flickr: //, aruncă codul FlickrBomb în partea de jos a paginii lor și, bam, au imagini substituente de la Flickr.

Funcționează excelent și cu aplicațiile web mari ol

Avem o mare aplicație web numită Notable, care a fost scrisă fără griji pentru generarea de conținut partea clientului. Când am vrut să facem secțiuni ale aplicației turbo încărcate prin generarea de conținut partea clientului, am ales Backbone. Motivele au fost aceleași: am vrut un cadru ușor care să ajute la menținerea codului organizat, dar să nu ne oblige să regândim întreaga aplicație.

Am lansat modificările la începutul acestui an cu mare succes și, de atunci, cântăm laude Backbones.

Resurse aditionale

Backbone are mult mai mult decât ceea ce am acoperit în acest articol, porțiunea C (controler) a MVC (model view controller) pentru începători, care este de fapt un R (router) în cea mai recentă versiune. Și totul este acoperit în documentația Backbone, o ușoară sâmbătă dimineață citea:
documentcloud.github.com/backbone/

Dacă vă interesează mai multe tutoriale tradiționale, verificați codul foarte bine documentat al acestei aplicații de todo scris în Backbone:
documentcloud.github.com/backbone/docs/todos.html

Noi Publicații
Cum să atragi o fantomă
Citeste Mai Mult

Cum să atragi o fantomă

Lucrul amuzant al de enării fantomelor e te - pre deo ebire de momentul în care de enezi oameni - te joci cu ur e de lumină upranaturale și ambianță în cena ta. Ace t lucru e te valabil mai ...
O introducere în căutarea căilor
Citeste Mai Mult

O introducere în căutarea căilor

Proiectarea are ca cop rezolvarea problemelor. O a tfel de problemă cu care ne confruntăm cu toții în fiecare zi e te cum ă ne depla ăm fără ă ne pierdem.De ignerii britanici au o formă con idera...
4 alternative la caietele de schițe tradiționale
Citeste Mai Mult

4 alternative la caietele de schițe tradiționale

Puține lucruri unt mai fundamentale pentru artiști și de igneri decât notebook-ul înșelător de umil. -ar putea ă arate ca niște pagini goale legate între ele într-o copertă robu tă...