Använd Backbone.js för att påskynda interaktioner

Författare: Monica Porter
Skapelsedatum: 13 Mars 2021
Uppdatera Datum: 15 Maj 2024
Anonim
Använd Backbone.js för att påskynda interaktioner - Kreativ
Använd Backbone.js för att påskynda interaktioner - Kreativ

Innehåll

Om du snabbt vill bygga ett litet JavaScript-verktyg tänker du förmodligen inte på att använda ett ramverk. Lättare att hacka ihop jQuery-kod snarare än att installera och lära sig ett nytt ramverk, eller hur? Fel, Backbone.js är ett superlätt limram som ser ut som det vanliga gamla JavaScript du brukade skriva.

Vi gör många statiska prototyper här på ZURB, för vi gillar att kunna klicka på sidor utan att behöva skriva någon backend-kod. Ofta släppte vi in ​​gråa platshållarbilder, eller ibland sökte vi Flickr efter exempelbilder för att hjälpa oss att visualisera vad som kan hända i det slutliga utkastet. Det är tills en magisk fredag, då vi bestämde oss för att det skulle vara fantastiskt att skriva lite JavaScript för att lösa våra problem. Vi ville kunna söka och välja foton på Flickr, direkt från själva platshållarbilderna. Vi skulle kalla det FlickrBomb, och det här är berättelsen om hur vi byggde den med Backbone.js.


Det rekommenderas starkt att du tittar snabbt på FlickrBomb innan du läser. Det är en av dessa erbjudanden "ett klick är värt tusen ord". Fortsätt, vi väntar.

Det finns många JavaScript-ramar på blocket dessa dagar, SproutCore, JavaScriptMVC, Spine, Sammy, Knockout. Men vi gillade Backbone.js för just detta projekt av några olika skäl:

1. Det är lätt (faktiskt 100% fettfritt)

  • i vikt, med den senaste packade versionen cirka 4,6 kb
  • i kod, som är drygt 1000 rader kod, är det inte väldigt svårt att följa en stapelspårning ner i internt utan att tappa sinnet

2. Det ser ut som JavaScript

  • eftersom det är JavaScript är det allt och allt
  • den använder jQuery, som även din mormor känner till idag

3. Super enkel uthållighet


  • ur lådan fortsätter den data till en backend (via REST), men genom att släppa in en enda plug-in kommer den att spara till lokal lagring istället
  • eftersom det tar bort persistens-API: et kan vi få det att bestå till en REST-backend genom att bara ta bort det lokala lagringspluginprogrammet

Låt oss börja då

Eftersom Backbone.js bara är JavaScript är allt vi behöver göra att inkludera det tillsammans med Underscore.js på sidan. jQuery är inte ett svårt beroende för Backbone i sig, men vi kommer att använda det så att vi tar med det här. Vi kopplar också upp det lokala lagringspluginprogrammet, eftersom vi inte vill krångla med att skapa en backend. Observera att länkar filerna direkt för enkelhetens skull, men du bör alltid vara värd för dina egna tillgångar 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>

All följande kod i den här artikeln är specifik för vår applikation, så vi kan inkludera den i en app.js-fil eller bara inline om det är din sak. Kom bara ihåg att inkludera det efter Backbone. Backbone gör det möjligt att abstraktera delar av vår applikation, för att göra dem båda modulära för enkel återanvändning och mer läsbara för andra. För att bäst illustrera den abstraktionen skulle vi förklara designen av FlickrBomb från botten uppifrån, med början med modellerna och slutade med vyerna.


Vår första modell

Den första uppgiften skulle hantera är att dra bilderna från Flickr. Att modellera en FlickrImage i ryggraden är enkelt nog, vi skapar en ny modell som heter FlickrImage och lägger till några metoder för att hjälpa oss att få olika tummar.

var FlickrImage = Backbone.Model.extend ({fullsize_url: function () {return this.image_url ('medium');}, thumb_url: function () {return this.image_url ('square');}, image_url: function ( storlek) {var size_code; switch (size) {case 'square': size_code = '_s'; break; // 75x75 case 'medium': size_code = '_z'; break; // 640 on the longest side case 'large ': size_code =' _b '; break; // 1024 på den längsta sidan standard: size_code =' ';} returnera "http: // farm" + this.get (' farm ') + ".static.flickr.com / "+ this.get ('server') +" / "+ this.get ('id') +" _ "+ this.get ('secret') + size_code +" .webp ";}})

Modeller i Backbone är objekt som kan bestå och har vissa funktioner associerade med dem, ungefär som modeller i andra MVC-ramar. Den magiska delen av Backbone-modeller är att vi kan binda händelser till attribut, så att när attributet ändras kan vi uppdatera våra åsikter för att återspegla det. Men vi går lite före oss själva.

När vi tar bilderna från Flickr kommer vi att få tillräckligt med information för att skapa webbadresser för alla storlekar. Men den samlingen lämnas åt oss, så vi implementerade .image_url () -funktionen som tar en storleksparameter och returnerar en offentlig länk. Eftersom detta är en ryggradsmodell kan vi använda this.get () för att komma åt attribut på modellen. Så med den här modellen kan vi göra följande någon annanstans i koden för att få URL till en Flickr-bild.

flickrImage.image_url ('large')

Ganska kortfattat, va? Eftersom den här modellen är specifik för vår applikation lägger vi till några omslagsfunktioner för storleksstorlek och tumbildsstorlek.

En samling bilder

FlickrBomb behandlar samlingar av bilder, inte enstaka bilder, och Backbone har ett bekvämt sätt att modellera detta. Den passande namngivna samlingen är vad vi ska använda för att gruppera Flickr-bilder för en enda platshållare.

var FlickrImages = Backbone.Collection.extend ({modell: FlickrImage, tangent: flickrbombAPIkey, sida: 1, hämta: funktion (nyckelord, framgång) {var själv = detta; framgång = framgång || $ .noop; this.keywords = nyckelord || this.keywords; $ .ajax ({url: 'http://api.flickr.com/services/rest/', data: {api_key: self.key, format: 'json', method: 'flickr. photos.search ', taggar: this.keywords, per_page: 9, sida: this.page, licens: flickrbombLicenseTypes}, dataType:' jsonp ', jsonp:' jsoncallback ', success: function (response) {self.add (respons .photos.photo); success ();}});}, nextPage: function (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);}});

Det finns ett par saker att notera här. Först och främst, modell attribut berättar samlingarna vilken typ av modell den samlar in. Vi har också några attribut som vi initierade för användning senare: nyckeln är vår Flickr API-nyckel, du vill ersätta flickrbombAPIkey med strängen i din egen Flickr API-nyckel. Att få en Flickr API-nyckel är gratis och enkelt, följ bara den här länken: www.flickr.com/services/api/misc.api_keys.html. Sidattributet är den aktuella sidan med Flickr-foton vi är på.

Den stora metoden här är .fetch (), som tar bort detaljerna för att dra foton från Flickr API. För att undvika problem med förfrågningar över flera domäner använder vi JSONP, som både Flickr API och jQuery stöder. De andra parametrarna som vi skickar till API: et bör vara självförklarande. Av särskilt intresse är ryggradsfunktionerna som kallas här. I den lyckade återuppringningen använder vi .add (), en funktion som tar en rad modellattribut, skapar modellinstanser från dessa attribut och lägger sedan till dem i samlingen.

Funktionerna .nextPage () och .prevPage () ändrar först sidan vi vill visa,
använd samlingsfunktionen .remove () för att ta bort alla befintliga modeller från
samling och ring sedan för att hämta foton för den aktuella sidan (som vi bara
ändrats).

FlickrBombImage

När vi jobbar oss tillbaka behöver vi ytterligare en modell för att representera platshållarbilden, som kommer att bestå av en samling FlickrImages och den aktuella FlickrImage som har valts. Vi kommer att kalla den här modellen 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 ('sökord'), this.loadFirstImage); this.set (id: this.get ("id")); this.bind ('ändra: src', this.changeSrc) ;}, changeSrc: function () {this.save ();}, loadFirstImage: function () {if (this.get ('src') === undefined) {this.set ({src: this.flickrImages. första (). image_url ()});}}});

Eftersom den här modellen är ansvarig för att hålla reda på den valda bilden mellan sidladdningar måste den veta vilken lokalbutik som ska användas.Den första raden säkerställer att det finns stöd för localstorage och skapa sedan den butik som vi använder för att bestå den valda bilden.

Med ryggraden kan vi definiera en .initialize () -funktion som kommer att anropas när en instans av modellen skapas. Vi använder den här funktionen i FlickrBombImage för att skapa en ny instans av FlickrImages-samlingen, skicka de nyckelord som ska användas för den här bilden och hämta sedan bilderna från Flickr.

Funktionen .loadFirstImage () har skickats som en återuppringning för att köras när bilderna har laddats från Flickr. Som du förmodligen kan gissa ställer den här funktionen in den aktuella bilden som den första i samlingen från Flickr. Det gör det inte om den aktuella bilden redan har ställts in.

Vi kommer också att använda Backbones attributåteruppringningar för att aktivera vår .changeSrc () -funktion när src-attributet för den här modellen ändras. Allt detta återuppringning gör är att ringa .save (), en funktion i ryggradsmodellen som fortsätter attributen för modellen till vilket lagerlager som helst som har implementerats (i vårt fall localstore). På detta sätt kvarstår den valda bilden omedelbart.

View Layer

Nu när vi har skrivit hela backend-koden (ja, frontend-backend) kan vi sätta ihop Views. Visningar i ryggraden är lite annorlunda än i andra traditionella MVC-ramar. Medan en vy vanligtvis bara handlar om sig själv med presentation, är en Backbone View också ansvarig för beteendet. Det betyder att din vy inte bara definierar hur något ser ut utan också vad det ska göra när det interageras med.

En vy är vanligt (men inte alltid) knuten till vissa data och går igenom tre faser för att generera presentationsmarkering från den informationen:

1. Visa-objektet initialiseras och ett tomt element skapas.
2. Renderingsfunktionen anropas och genererar markeringen för vyn genom att infoga den i det element som skapades i föregående steg.
3. Elementet är fäst vid DOM.

Det kan tyckas som mycket arbete för att generera en viss markering, och vi är inte ens i beteende delen av vyn ännu, men det är viktigt, och här är varför. Varje gång du ändrar element som finns i DOM, utlöser du något som kallas ett webbläsarflöde. Ett återflöde är webbläsaren som beräknar hur varje sak på sidan är placerad. Webbläsaråterflöden kan vara dåliga för prestanda om de anropas inom en händelse för att dra eller ändra storlek, som avfyras med ett mycket kort intervall, men värre, de ser slarviga ut. Med komplex sidmanipulation kan du faktiskt se att element läggs till på sidan och att element påverkas om. Efter Backbones mönster för initialisering, rendering och bifogning garanterar du ett enda återflöde, och ändringarna på sidan kommer att uppfattas omedelbart, oavsett komplexiteten i elementmanipulation.

FlickrBombImageView

var FlickrBombImageView = Backbone.View.extend ({tagName: "div", className: "flickrbombContainer", lock: false, mall: _.template ('div id = "% = this.image.id.replace (" ", "")%> "... / div> '), initialisera: funktion (alternativ) {_.bindAll (detta,' addImage ',' updateSrc ',' setDimentions ',' updateDimentions '); var nyckelord = alternativ. img.attr ('src') .replace ('flickr: //', ''); detta. $ el = $ (this.el); this.image = new FlickrBombImage ({sökord: nyckelord, id: alternativ. img.attr ('id')}); this.image.flickrImages.bind ('add', this.addImage); this.image.bind ('ändra: src', this.updateSrc);}, händelser: { "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;}, ...});

Funktionerna i denna vy har utelämnats för korthet, källkoden i sin helhet finns på GitHub: github.com/zurb/flickrbomb

Högst upp i vyn har vi ett par specifika attribut för ryggraden. tagName och className används för att definiera taggen och klassen som ska tillämpas på den här vyn. Kom ihåg att steg 1 i Visa skapande är att skapa ett objekt, och eftersom den skapandet hanteras av Backbone måste vi ange elementet och klassen. Observera att Backbone har förnuftiga standardvärden; om vi utelämnar dessa attribut används en div som standard och ingen klass tillämpas om du inte anger en.

Mallattributet är en konvention, men krävs inte. Vi använder den här för att specificera JavaScript-mallfunktionen som vi använder för att skapa vår markering för den här vyn. Vi använder funktionen _.template () som ingår i Underscore.js, men du kan använda vilken mallmotor du helst föredrar, vi kommer inte att döma dig.

I vår .initialize () -funktion drar vi ut nyckelordsträngen från bildtaggen och skapar sedan en FlickrBombImage-modell med hjälp av dessa nyckelord. Vi bindar också funktionen .addImage () som ska köras när en FlickrImage läggs till i FlickrImages-samlingen. Denna funktion kommer att lägga till den nyligen tillagda FlickrImage till vår bildväljare. Den sista och viktigaste raden är att binda .updateSrc () -funktionen till att aktiveras när den för närvarande valda FlickrImage ändras. När den aktuella bilden ändras i modellen kommer den här funktionen att köras, uppdatera bildelementets src-attribut och CSS ändra storlek och beskära bilden så att den passar inom de bilddimensioner som användaren anger.

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

Efter .initialize () har vi beteende delen av vyn. Backbone är ett bekvämt sätt att binda händelser med hjälp av ett händelseobjekt. Händelserobjektet använder metoden jQuery .delegate () för att göra den faktiska bindningen till Visa-elementet, så att alla dina bundna händelser fortfarande fungerar oavsett vilken manipulation du gör mot elementet i vyn. Det fungerar precis som jQuery .live (), förutom att du istället för att binda händelser till hela dokumentet kan binda dem inom ramen för vilket element som helst. Nyckeln till varje post i händelseobjektet består av händelsen och väljaren, värdet indikerar den funktion som ska vara bunden till den händelsen. Observera att .delegate () inte fungerar med vissa händelser som skicka, se dokumentationen jQuery .live () för en fullständig lista över stödda händelser.

render: function () {$ (this.el) .html (this.template ()); this.image.fetch (); this.resize (); returnera detta;}

Slutligen har vi .render () -funktionen som är ansvarig för att skapa vår markering och utföra ytterligare arbete som inte kan utföras förrän View-markeringen har lagts till i View-elementet. När vi har gjort vår mall måste vi ringa .fetch () på vår FlickrBombImage. .fetch () är en ryggradsfunktion som får den senaste kopian av modellen från uthållighetsskiktet. Om vi ​​hade sparat den här modellen tidigare skulle .fetch () hämta den informationen nu. Efter att bilden har hämtats måste vi ringa storlek för att placera den korrekt.

Hemsträckan

Med alla bitar på plats är allt vi behöver göra nu att hitta platshållarbilderna på sidan och ersätta dem med de renderade FlickrBombImage-vyerna.

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

Det här lilla utdraget måste köras längst ner på sidan eller i en dokumentklar återuppringning för att säkerställa att den kan hitta de platshållarbilder som den kommer att ersätta. Vi använder konventionen om att specificera flickr: // [KEYWORD] i src-attributet för en bildtagg för att indikera att den ska fyllas med bilder från Flickr. Vi hittar bildelement med ett matchande src-attribut, skapar en ny FlickrBombImageView och ersätter sedan bilden med vår. Vi tar en kopia av originalbilden och skickar den till vår FlickrBombView, så att vi kan dra några ytterligare konfigurationsalternativ som kan ha specificerats på elementet.

Slutresultatet av allt det hårda arbetet är ett mycket enkelt API för personer som använder biblioteket. De kan helt enkelt definiera bildtaggar med hjälp av flickr: //-konventionen, släppa FlickrBomb-koden längst ner på sidan och bam, de har platshållarbilder från Flickr.

Fungerar också bra med stora ol-webbappar

Vi har en stor ol-webbapp som heter Notable, som skrevs utan oro för att skapa innehåll på klientsidan. När vi ville ladda avsnitt av appen turbo genom att generera innehållsklientsidan, valde vi Backbone. Orsakerna var desamma: vi ville ha en lätt ram för att hålla koden organiserad, men inte tvinga oss att ompröva hela applikationen.

Vi lanserade förändringarna tidigare i år med stor framgång och har sjungit Backbones beröm sedan dess.

Ytterligare resurser

Det finns mycket mer i Backbone än vad jag täckte i den här artikeln, C (controller) -delen av MVC (modellvy controller) till att börja med, som faktiskt är en R (router) i den senaste versionen. Och allt omfattas av dokumentationen för ryggraden, en lätt lördag morgon läser:
documentcloud.github.com/backbone/

Om mer traditionella handledning är din grej, kolla in den väldokumenterade koden för denna todo-applikation skriven i Backbone:
documentcloud.github.com/backbone/docs/todos.html

Val Av Läsare
Fem bästa tips för att ge designfeedback
Läs Mer

Fem bästa tips för att ge designfeedback

Att för tå p ykologin bakom ociala interaktioner är ett jobb i ig, men när du foku erar på ikoner, rutnät, interaktioner är det lätt att förbi e att andra ...
Hur man kodar smarta texteffekter med CSS
Läs Mer

Hur man kodar smarta texteffekter med CSS

Övergång länkar är ett utmärkt ätt att fånga användaren uppmärk amhet, är kilt om de gör något ovanligt eller originellt. Middle Child har e...
5 klassiska filmaffischer från Anthony Goldschmidt
Läs Mer

5 klassiska filmaffischer från Anthony Goldschmidt

Den 17 juni dog tyvärr en av pionjärerna inom filmaffi chde ign. Anthony Gold chmidt grundade Intralink Film Grafi k De ign 1979 och var den enda ägaren av företaget edan tarten. G...