Brug Backbone.js til at fremskynde interaktioner

Forfatter: Monica Porter
Oprettelsesdato: 13 Marts 2021
Opdateringsdato: 15 Kan 2024
Anonim
Web Apps of the Future with React by Neel Mehta
Video.: Web Apps of the Future with React by Neel Mehta

Indhold

Hvis du hurtigt vil oprette et lille JavaScript-værktøj, tænker du sandsynligvis ikke på at bruge en ramme. Lettere at hacke sammen jQuery-kode i stedet for at installere og lære en ny ramme, ikke? Forkert, Backbone.js er en super let limramme, der ligner det almindelige gamle JavaScript, du plejede at skrive.

Vi laver mange statiske prototyper her på ZURB, fordi vi kan lide at være i stand til at klikke igennem sider uden at skulle skrive nogen backend-kode. Ofte tabte vi dystre grå pladsholderbilleder, eller nogle gange søgte vi Flickr efter prøvebilleder for at hjælpe os med at visualisere, hvad der kunne komme med i det endelige kladde. Det er indtil en magisk fredag, da vi besluttede, at det ville være fantastisk at skrive noget JavaScript for at løse vores problemer. Vi ønskede at være i stand til at søge og vælge fotos på Flickr direkte fra selve pladsholderbillederne. Vi vil kalde det FlickrBomb, og dette er historien om, hvordan vi byggede det ved hjælp af Backbone.js.


Det anbefales stærkt, at du kigger hurtigt på FlickrBomb, før du læser. Det er en af ​​disse "tilbud på et klik er tusind ord værd". Fortsæt, vi venter.

Der er mange JavaScript-rammer på blokken i disse dage, SproutCore, JavaScriptMVC, Spine, Sammy, Knockout. Men vi kunne lide Backbone.js til dette projekt af nogle få forskellige grunde:

1. Det er let (faktisk 100% fedtfrit)

  • i vægt, hvor den seneste pakkede version er cirka 4,6 kb
  • i kode, der er lidt over 1.000 linjer kode, er det ikke frygteligt svært at følge en staksporing ned i det indre uden at miste tankerne

2. Det ligner JavaScript

  • fordi det er JavaScript, det er det, og det er alt
  • det bruger jQuery, som selv din bedstemor kender i disse dage

3. Super simpel vedholdenhed


  • ud af kassen fortsætter det data til en backend (via REST), men ved at droppe et enkelt plug-in gemmes det i stedet for lokal lagring
  • fordi det abstraherer persistens-API'en, kan vi få det til at forblive i en REST-backend ved blot at fjerne det lokale lager-plug-in

Lad os komme i gang dengang

Da Backbone.js bare er JavaScript, er alt, hvad vi skal gøre, at inkludere det sammen med Underscore.js på siden. jQuery er ikke en hård afhængighed for Backbone i sig selv, men vi vil bruge det, så vi inkluderer det her. Vi forbinder også det lokale lager-plug-in, da vi ikke vil besvære med at oprette en backend. Bemærk, at der var en direkte sammenkædning mellem filerne her, men du skal altid være vært for dine egne aktiver i produktionen.

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>

Alle følgende koder i denne artikel er specifikke for vores applikation, så vi kan inkludere den i en app.js-fil eller bare inline, hvis det er dine ting. Husk bare at inkludere det efter Backbone. Backbone gør det muligt at abstrakte dele af vores applikation og gøre dem begge modulære for nem genbrug og mere læsbare for andre. For bedst at illustrere denne abstraktion skulle vi forklare designet af FlickrBomb fra bunden op, startende med modellerne og sluttede med udsigterne.


Vores første model

Den første opgave, der skulle tackles, er at trække billederne fra Flickr. Modellering af en FlickrImage i rygraden er enkel nok, vi opretter en ny model kaldet FlickrImage og tilføjer nogle metoder til at hjælpe os med at få tommelfingre i forskellige størrelser.

var FlickrImage = Backbone.Model.extend ({fullsize_url: function () {return this.image_url ('medium');}, thumb_url: function () {return this.image_url ('square');}, image_url: function ( størrelse) {var size_code; switch (størrelse) {case 'square': size_code = '_s'; break; // 75x75 case 'medium': size_code = '_z'; break; // 640 på den længste side case 'large ': size_code =' _b '; break; // 1024 på den længste side standard: size_code =' ';} returner "http: // farm" + this.get (' farm ') + ".static.flickr.com / "+ this.get ('server') +" / "+ this.get ('id') +" _ "+ this.get ('secret') + size_code +" .webp ";}})

Modeller i Backbone er objekter, der kan vedholdes, og som nogle funktioner er knyttet til dem, ligesom modeller i andre MVC-rammer. Den magiske del af Backbone-modeller er, at vi kan binde begivenheder til attributter, så når denne attribut ændres, kan vi opdatere vores synspunkter for at afspejle det. Men vi kommer lidt foran os selv.

Når vi trækker billederne fra Flickr, får vi nok information til at oprette webadresser til alle størrelser. Imidlertid overlades denne samling til os, så vi implementerede .image_url () -funktionen, der tager en størrelsesparameter og returnerer et offentligt link. Da dette er en rygradsmodel, kan vi bruge this.get () til at få adgang til attributter på modellen. Så med denne model kan vi gøre følgende andetsteds i koden for at få URL'en til et Flickr-billede.

flickrImage.image_url ('stor')

Temmelig kortfattet, ikke? Da denne model er specifik for vores applikation, tilføjer vi nogle indpakningsfunktioner til størrelsen fuld størrelse og tommelfinger.

En samling af billeder

FlickrBomb beskæftiger sig med samlinger af billeder, ikke enkeltbilleder, og Backbone har en praktisk måde at modellere dette på. Den passende navngivne samling er det, vi bruger til at gruppere Flickr-billeder sammen til en enkelt pladsholder.

var FlickrImages = Backbone.Collection.extend ({model: FlickrImage, nøgle: flickrbombAPIkey, side: 1, hent: funktion (nøgleord, succes) {var self = dette; succes = succes || $ .noop; this.keywords = nøgleord || this.keywords; $ .ajax ({url: 'http://api.flickr.com/services/rest/', data: {api_key: self.key, format: 'json', metode: 'flickr. photos.search ', tags: this.keywords, per_page: 9, side: this.page, licens: flickrbombLicenseTypes}, dataType:' jsonp ', jsonp:' jsoncallback ', success: function (response) {self.add (respons .photos.photo); succes ();}});}, nextPage: funktion (callback) {this.page + = 1; this.remove (this.models); this.fetch (null, callback);}, prevPage: function (callback) {if (this.page> 1) {this.page - = 1;} this.remove (this.models); this.fetch (null, callback);}});

Der er et par ting at bemærke her. Først og fremmest model attribut fortæller samlingerne, hvilken type model den samler. Vi har også nogle attributter, som vi initialiserede til brug senere: nøglen er vores Flickr API-nøgle, du vil erstatte flickrbombAPIkey med strengen i din egen Flickr API-nøgle. At få en Flickr API-nøgle er gratis og let, følg bare dette link: www.flickr.com/services/api/misc.api_keys.html. Sideattributten er den aktuelle side med Flickr-fotos, vi er på.

Den store metode her er .fetch (), som abstraherer detaljerne i at trække fotos fra Flickr API. For at undgå problemer med anmodninger på tværs af domæner bruger vi JSONP, som både Flickr API og jQuery understøtter. De andre parametre, vi overfører til API'en, skal være selvforklarende. Af særlig interesse er Backbone-funktionerne, der kaldes her. I den tilbagekaldelse af succes, vi bruger .add (), en funktion, der tager en række modelattributter, opretter modelforekomster fra disse attributter og føjer dem derefter til samlingen.

Funktionerne .nextPage () og .prevPage () ændrer først den side, vi vil vise,
brug indsamlingsfunktionen .remove () for at fjerne alle eksisterende modeller fra
samling, og ring derefter for at hente fotos for at få den aktuelle side (som vi bare
ændret).

FlickrBombImage

Når vi arbejder op igen, har vi brug for endnu en model til at repræsentere pladsholderbilledet, som vil bestå af en samling af FlickrImages og den aktuelle FlickrImage, der er valgt. Vi kalder denne model FlickrBombImage.

var localStorage = (understøtter_local_storage ())? ny butik ("flickrBombImages"): null; var FlickrBombImage = Backbone.Model.extend ({localStorage: localStorage, initialize: function () {_.bindAll (this, 'loadFirstImage'); this.flickrImages = new FlickrImages (); this.flickrImages.fetch (this.get ('keywords'), this.loadFirstImage); this.set (id: this.get ("id")); this.bind ('change: src', this.changeSrc) ;}, changeSrc: funktion () {this.save ();}, loadFirstImage: function () {if (this.get ('src') === udefineret) {this.set ({src: this.flickrImages. første (). image_url ()});}}});

Da denne model er ansvarlig for at holde styr på det aktuelt valgte billede mellem sideindlæsninger, skal den vide, hvilken lokalbutik der skal bruges.Den første linje vil sikre, at der er understøttelse af localstorage, og derefter oprette den butik, vi vil bruge til at fastholde det valgte billede.

Backbone giver os mulighed for at definere en .initialize () - funktion, der kaldes, når en forekomst af modellen oprettes. Vi bruger denne funktion i FlickrBombImage til at oprette en ny forekomst af FlickrImages-samlingen, videregive de nøgleord, der vil blive brugt til dette billede, og derefter hente billederne fra Flickr.

Funktionen .loadFirstImage () er sendt som en tilbagekaldelse for at køre, når billederne er blevet indlæst fra Flickr. Som du sikkert kan gætte, indstiller denne funktion det aktuelle billede til at være det første i samlingen fra Flickr. Det gør det ikke, hvis det aktuelle billede allerede er indstillet.

Vi vil også bruge Backbones attribut-tilbagekald til at udløse vores .changeSrc () -funktion, når src-attributten for denne model ændres. Alt dette tilbagekald gør er at kalde .save (), en Backbone-modelfunktion, der fortsætter modelens attributter til det lagerlag, der er implementeret (i vores tilfælde localstore). På denne måde vedvares det valgte billede straks, når det valgte billede ændres.

Visningslaget

Nu hvor vi har skrevet al backend (godt, frontend backend) kode, kan vi sammensætte Views. Visninger i backbone er lidt forskellige fra andre traditionelle MVC-rammer. Mens en visning typisk kun vedrører sig selv med præsentation, er en Backbone View også ansvarlig for adfærd. Det betyder, at din visning ikke kun definerer, hvordan noget ser ud, men også hvad det skal gøre, når det interageres med.

En visning er almindeligt (men ikke altid) bundet til nogle data og går gennem tre faser for at generere præsentationsmarkering ud fra disse data:

1. Vis-objektet initialiseres, og der oprettes et tomt element.
2. Gengivelsesfunktionen kaldes og genererer markeringen til visningen ved at indsætte den i det element, der blev oprettet i det foregående trin.
3. Elementet er fastgjort til DOM.

Dette kan virke som en masse arbejde for at generere en vis markering, og vi er ikke engang til adfærdsdelen af ​​visningen endnu, men det er vigtigt, og her er hvorfor. Hver gang du ændrer elementer, der er i DOM, udløser du noget, der kaldes en browser reflow. Et omløb er browseren, der genberegner, hvordan hver ting på siden er placeret. Browsereflows kan være dårlige for ydeevnen, hvis de kaldes inden for en træk- eller størrelsesbegivenhed, der udløses med et meget kort interval, men værre, de ser sjusket ud. Med kompleks sidemanipulation kan du faktisk se elementer, der føjes til siden, og påvirkede elementer omplaceres. Efter Backbones mønster med initialisering, gengivelse og vedhæftning garanterer du et enkelt omløb, og ændringerne på siden bliver øjeblikkeligt øjeblikkelig, uanset kompleksiteten af ​​elementmanipulation.

FlickrBombImageView

var FlickrBombImageView = Backbone.View.extend ({tagName: "div", className: "flickrbombContainer", lock: false, template: _.template ('div id = "% = this.image.id.replace (" ", "")%> "... / div> '), initialiser: funktion (optioner) {_.bindAll (dette,' addImage ',' updateSrc ',' setDimentions ',' updateDimentions '); var nøgleord = optioner. img.attr ('src') .placering ('flickr: //', ''); dette. $ el = $ (this.el); this.image = ny FlickrBombImage ({nøgleord: nøgleord, id: muligheder. img.attr ('id')}); this.image.flickrImages.bind ('add', this.addImage); this.image.bind ('change: src', this.updateSrc);}, events: { "click .setupIcon": "clickSetup", "click .flickrbombFlyout a.photo": "selectImage", "click .flickrbombFlyout a.next": "nextFlickrPhotos", "click .flickrbombFlyout a.prev": "prevFlickrPhotos"}, gengiv: funktion () {$ (this.el) .html (this.template ()); this.image.fetch (); this.resize (); returner dette;}, ...});

Funktionerne i denne visning er udeladt for kortfattethed, kildekoden i sin helhed er tilgængelig på GitHub: github.com/zurb/flickrbomb

Øverst i visningen har vi et par backbone-specifikke attributter. tagName og className bruges til at definere det tag og class, der skal anvendes på denne visnings element. Husk, at trin et i Vis oprettelse opretter et objekt, og da oprettelsen håndteres af Backbone, er vi nødt til at specificere elementet og klassen. Bemærk, at backbone har fornuftige standardindstillinger; hvis vi udelader disse attributter, bruges en div som standard, og der anvendes ingen klasse, medmindre du angiver en.

Skabelonattributten er en konvention, men ikke påkrævet. Vi bruger det her til at specificere JavaScript-skabelonfunktionen, som vi bruger til at generere vores markering for denne visning. Vi bruger funktionen _.template () inkluderet i Underscore.js, men du kan bruge den skabelonmotor, du foretrækker, vi bedømmer dig ikke.

I vores .initialize () -funktion trækker vi nøgleordstrengen ud af billedkoden og opretter derefter en FlickrBombImage-model ved hjælp af disse nøgleord. Vi binder også funktionen .addImage (), der skal køres, når en FlickrImage føjes til FlickrImages-samlingen. Denne funktion tilføjer den nyligt tilføjede FlickrImage til vores billedvælgerflyout. Den sidste og vigtigste linje binder funktionen .updateSrc () til at affyre, når den aktuelt valgte FlickrImage ændres. Når det aktuelle billede ændres i modellen, kører denne funktion, opdaterer src-attributten for billedelementet, og CSS ændrer størrelse og beskærer billedet for at passe inden for de billeddimensioner, der er angivet af brugeren.

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

Efter .initialize () har vi opførselsdelen af ​​visningen. Rygraden giver en bekvem måde at binde begivenheder ved hjælp af et begivenhedsobjekt. Hændelsesobjektet bruger metoden jQuery .delegate () til at udføre den faktiske binding til visningselementet, så uanset hvilken manipulation du udfører til elementet inde i visningen, fungerer alle dine bundne begivenheder stadig. Det fungerer ligesom jQuery .live (), bortset fra at i stedet for at binde begivenheder til hele dokumentet, kan du binde dem inden for ethvert element. Nøglen til hver post i begivenhedsobjektet består af begivenheden og vælgeren, værdien angiver den funktion, der skal være bundet til den begivenhed. Bemærk, at .delegate () ikke fungerer med nogle begivenheder som f.eks. Indsendelse, se dokumentationen jQuery .live () for en komplet liste over understøttede begivenheder.

gengive: funktion () {$ (this.el) .html (this.template ()); this.image.fetch (); this.resize (); returner dette;}

Endelig har vi .render () -funktionen, der er ansvarlig for at oprette vores markup og udføre ethvert ekstra arbejde, der ikke kan udføres, før View-markeringen er blevet føjet til View-elementet. Når vi har gengivet vores skabelon, skal vi kalde .fetch () på vores FlickrBombImage. .fetch () er en backbone-funktion, der får den seneste kopi af modellen fra persistenslaget. Hvis vi havde gemt denne model før, ville .fetch () hente disse data nu. Når billedet er hentet, skal vi kalde størrelse for at placere det korrekt.

Hjemmestrækningen

Med alle brikkerne på plads er alt, hvad vi skal gøre nu, at finde pladsholderbillederne på siden og erstatte dem med de gengivne FlickrBombImage-visninger.

$ ("img [src ^ = 'flickr: //']"). hver (funktion () {var img = $ (dette), flickrBombImageView = ny FlickrBombImageView ({img: img}); img.replaceWith (flickrBombImageView. gengive (). el);});

Dette lille klip skal køres i bunden af ​​siden eller i et dokument klar tilbagekaldelse for at sikre, at det kan finde de pladsholderbilleder, det vil erstatte. Vi bruger konventionen om at angive flickr: // [KEYWORD] i src-attributten for et billedkode for at angive, at det skal udfyldes med billeder fra Flickr. Vi finder billedelementer med en matchende src-attribut, opretter en ny FlickrBombImageView og erstatter derefter billedet med vores. Vi tager en kopi af det originale billede og sender det til vores FlickrBombView, så vi kan trække nogle yderligere konfigurationsindstillinger, der muligvis er blevet specificeret på elementet.

Slutresultatet af alt det hårde arbejde er en meget enkel API for folk, der bruger biblioteket. De kan simpelthen definere billedkoder ved hjælp af flickr: //-konventionen, slippe FlickrBomb-koden nederst på deres side og bam, de har pladsholderbilleder fra Flickr.

Fungerer også godt med store ol webapps

Vi har en stor webapp kaldet Notable, der blev skrevet uden bekymring for at generere indhold på klientsiden. Da vi ønskede at oplade sektioner af app-turboen ved at generere indholdsklientsiden, valgte vi Backbone. Årsagerne var de samme: Vi ønskede en letvægtsramme til at holde koden organiseret, men ikke tvinge os til at genoverveje hele applikationen.

Vi lancerede ændringerne tidligere på året med stor succes og har sunget Backbones ros lige siden.

Yderligere ressourcer

Der er meget mere til Backbone end hvad jeg dækkede i denne artikel, C (controller) -delen af ​​MVC (model view controller) til at begynde med, hvilket faktisk er en R (router) i den nyeste version. Og det hele er dækket af Backbone-dokumentationen, en let lørdag morgen læses:
documentcloud.github.com/backbone/

Hvis mere traditionelle tutorials er dine ting, så tjek den meget veldokumenterede kode for denne todo-applikation skrevet i Backbone:
documentcloud.github.com/backbone/docs/todos.html

Anbefalede
Sådan maler du en spøgelsesagtig figur i Photoshop
Læs Mere

Sådan maler du en spøgelsesagtig figur i Photoshop

At kabe pøgel e former med en gennem kinnelig effekt kan være lidt kræmmende, men jeg bruger en impel teknik, der kan anvende på mange ting, hvor du muligvi har brug for en gennem ...
5 hemmeligheder bag en vellykket illustrationskarriere
Læs Mere

5 hemmeligheder bag en vellykket illustrationskarriere

At tegne en ucce rig karriere om illu tratør handler ikke kun om kun tneri k dygtighed - det handler og å om at have den rigtige holdning og gå på tingene på den rigtige m...
Sådan oprettes en progressiv webapp
Læs Mere

Sådan oprettes en progressiv webapp

Mobil tegner ig nu for over halvdelen af ​​internettrafikken, og webapplikationer giver brugerne mulighed for at gøre ting i brow eren, der konkurrerer med indfødte app , men der er et probl...