Aan de slag met Backbone.js

In tegenstelling tot zijn collega's op het gebied van webontwikkeling, heeft JavaScript nooit echt veel structuur op het gebied van frameworks gehad. Gelukkig begint dat de afgelopen jaren te veranderen.

Vandaag wil ik je kennis laten maken met Backbone.JS, een lieve kleine bibliotheek die het proces van het maken van complexe, interactieve en gegevensgestuurde apps zoveel eenvoudiger maakt. Het biedt een schone manier om uw gegevens operatief van uw presentatie te scheiden.


Overzicht van Backbone.JS

Gemaakt door Jeremy Ashkenas, de JS ninja die CoffeeScript heeft gebouwd, Backbone is een superlichtgewicht bibliotheek waarmee je eenvoudig frontends kunt maken. Het is back-end agnostisch en werkt goed met alle moderne JavaScript-bibliotheken die u al gebruikt.

Backbone is een verzameling samenhangende objecten, die in een schaduw eronder wegen 4KB, die structuur aan uw code verlenen en u in principe helpt bij het bouwen van een geschikte MVC-app in de browser. De officiële site beschrijft zijn doel als zo:

Backbone levert structuur aan JavaScript-zware toepassingen door modellen te voorzien van sleutelwaardebinding en aangepaste gebeurtenissen, collecties met een rijke API van talloze functies, weergaven met declaratieve gebeurtenisafhandeling en verbindt deze allemaal met uw bestaande applicatie via een RESTful JSON-interface.

Laten we eerlijk zijn: het bovenstaande is een beetje moeilijk te ontleden en te begrijpen. Dus laten we doorgaan en het jargon een beetje deconstrueren, met hulp van Jeremy.

Key-value binding en aangepaste evenementen

Wanneer de inhoud of status van een model wordt gewijzigd, worden andere objecten die zich op het model hebben geabonneerd, hiervan op de hoogte gebracht, zodat ze kunnen doorgaan. Hier luisteren de weergaven naar wijzigingen in het model en werken ze dienovereenkomstig bij in plaats van dat het model handmatig met de aanzichten moet omgaan.

Rich API met opsombare functies

Backbone wordt geleverd met een aantal zeer nuttige functies voor het verwerken van en werken met uw gegevens. In tegenstelling tot andere implementaties, zijn arrays in JavaScript behoorlijk gecastreerd, wat echt een belemmerend probleem is als je te maken hebt met gegevens.

Weergaven met declaratieve afhandeling van gebeurtenissen

Je dagen om spaghetti-bind-gesprekken te schrijven zijn voorbij. U kunt programmatisch aangeven welke callback moet worden gekoppeld aan specifieke elementen.

RESTful JSON-interface

Hoewel de standaardmethode is om een ​​standaard AJAX-oproep te gebruiken wanneer u met de server wilt praten, kunt u deze gemakkelijk uitschakelen voor alles wat u nodig hebt. Er zijn een aantal adapters op de markt verschenen die de meeste favorieten omvatten, waaronder Websockets en lokale opslag.

Om het nog eenvoudiger te maken:

Backbone biedt een schone manier om uw gegevens operatief van uw presentatie te scheiden. Het model dat met de gegevens werkt, heeft alleen betrekking op synchronisatie met een server, terwijl de primaire taak van het beeld is luisteren naar wijzigingen in het geabonneerde model en het weergeven van de HTML.


Een snelle veelgestelde vragen

Ik vermoed dat je op dit moment waarschijnlijk een beetje bent verdoofd, dus laten we een paar dingen ophelderen:

Vervangt het jQuery?

Nee. Ze zijn vrij complementair in hun scopes met bijna geen overlappingen in functionaliteit. Backbone verwerkt alle abstracties van een hoger niveau, terwijl jQuery - of soortgelijke bibliotheken - met de DOM werken, gebeurtenissen normaliseren enzovoort.

Hun scopes en use-cases zijn behoorlijk verschillend en omdat je iemand kent, wil dat nog niet zeggen dat je de ander niet moet leren. Als JavaScript-ontwikkelaar moet u weten hoe u effectief met beide kunt werken.

Waarom zou ik dit gebruiken??

Omdat vaker dan niet de frontendcode uitgroeit tot een stomende, vuile stapel geneste callbacks, DOM-manipulaties, HTML voor de presentatie te midden van andere onoverwinnelijke handelingen.

Backbone biedt een aanzienlijk schone en elegante manier om deze chaos te beheersen.

Waar moet ik dit gebruiken??

Backbone is bij uitstek geschikt voor het maken van zware, datagedreven applicaties aan de voorkant. Denk aan de GMail-interface, nieuwe Twitter of enige andere openbaring van de afgelopen jaren. Het maakt het creëren van complex apps gemakkelijker.

Terwijl u het voor meer mainstream web kunt shoehorn pagina's, dit is echt een bibliotheek die is afgestemd op web-apps.

Is het vergelijkbaar met Cappuccino of Sproutcore?

Ja en nee.

Ja, want net als de bovengenoemde frameworks is dit vooral bedoeld voor het maken van complexe frontends voor webtoepassingen.

Het is ongelijk in dat Backbone vrij mager is, en wordt geleverd met geen van de widget die de anderen leveren.

Backbone is ongelooflijk licht van gewicht, minder dan 4 kb.

Er is ook het feit dat Cappuccino je dwingt om je code te schrijven in Objective-J, terwijl de standpunten van Sproutcore in JS programmatisch moeten worden verklaard. Hoewel geen van deze benaderingen verkeerd is, met Backbone, wordt normaal JavaScript gebruikt door uw gewone HTML en CSS om dingen voor elkaar te krijgen, wat leidt tot een zachtere leercurve.

Ik kan nog steeds andere bibliotheken op de pagina gebruiken, toch??

Absoluut. Niet alleen je typische DOM-toegang, AJAX-verpakkingstype, maar ook de rest van je template en het laden van sjablonen. Het is heel, heel los gekoppeld, wat betekent dat je bijna al je gereedschappen kunt gebruiken in combinatie met Backbone.

Zal het de wereldvrede inluiden?

Nee sorry. Maar hier is iets om je op te vrolijken.

OK, nu met dat uit de weg, laten we erin duiken!


De backbone van Backbone leren kennen

Het MVC in Backbone stond oorspronkelijk voor Modellen, Visies en Collecties, omdat er geen controllers in het kader waren. Dit is sindsdien veranderd.

De kern van Backbone bestaat uit vier hoofdklassen:

  • Model
  • Verzameling
  • Uitzicht
  • controleur

Omdat we een tijdje vastzitten, laten we vandaag alleen de kernklassen bekijken. We gaan een vervolg-tut doen met een supereenvoudige app om de hier onderwezen concepten te demonstreren, omdat het te veel zou zijn om alles in één artikel te plaatsen en van de lezer te verwachten dat hij alles zou ontleden.

Houd je ogen open gedurende de komende paar weken!


Model

Modellen kunnen verschillende dingen betekenen in verschillende implementaties van MVC. In Backbone vertegenwoordigt een model een unieke entiteit - een record in een database als u wilt. Maar hier zijn geen harde en snelle regels. Van de Backbone-website:

Modellen vormen het hart van elke JavaScript-toepassing en bevatten de interactieve gegevens en een groot deel van de logica eromheen: conversies, validaties, berekende eigenschappen en toegangscontrole.

Het model geeft u slechts een manier om willekeurige eigenschappen of attributen in een dataset te lezen en te schrijven. Met dat in gedachten is de enkele voering hieronder volledig functioneel:

 var Game = Backbone.Model.extend ();

Laten we hier een beetje op bouwen.

 var Game = Backbone.Model.extend (initialize: function () alert ("Oh hey!");, standaardinstellingen: name: 'Default title', releaseDate: 2011,);

initialiseren wordt geactiveerd wanneer een object wordt geïnstantieerd. Hier waarschuw ik je alleen voor onbenulligheden. In je app zou je waarschijnlijk je gegevens moeten booten of een andere huishouding moeten uitvoeren. Ik definieer ook een aantal standaardinstellingen, voor het geval er geen gegevens worden doorgegeven.

Laten we eens kijken hoe je attributen moet lezen en schrijven. Maar laten we eerst een nieuw exemplaar maken.

 // Maak een nieuwe game var portal = new Game (name: "Portal 2", releaseDate: 2011); // release behoudt de releaseDate waarde - 2011 hier var release = portal.get ('releaseDate'); // Wijzigt het naamkenmerk portal.set (name: "Portal 2 by Valve");

Als je de get / set mutators hebt opgemerkt, heb dan een koekje! De kenmerken van een model kunnen niet worden gelezen door uw typische object.attribute-indeling. Je zult door de getter / setter moeten omdat er een kleinere kans is dat je per ongeluk gegevens wijzigt.

Op dit moment worden alle wijzigingen alleen in het geheugen bewaard. Laten we deze wijzigingen permanent maken door met de server te praten.

 portal.save ();

Dat is het. Verwachtte je meer? De bovenstaande one-liner stuurt nu een aanvraag naar uw server. Houd er rekening mee dat het type verzoek op intelligente wijze zal veranderen. Omdat dit een nieuw object is, wordt POST gebruikt. Anders wordt PUT gebruikt.

Er zijn veel meer functies, Backbone-modellen geven je standaard, maar hiermee moet je zeker beginnen. Klik op de documentatie voor meer informatie.


Verzameling

Collecties in Backbone zijn in essentie slechts een verzameling modellen. Gaan met onze database-analogie van vroeger, verzamelingen zijn de resultaten van een query waarbij de resultaten uit een aantal records bestaan ​​[modellen]. U kunt een verzameling als volgt definiëren:

 var GamesCollection = Backbone.Collection.extend (model: Game,);

Het eerste om op te merken is dat we bepalen welk model dit een verzameling is. Uitgebreider naar ons voorbeeld, ik maak van deze verzameling een verzameling spellen.

Nu kunt u doorgaan en spelen met uw gegevens naar hartenlust. Laten we bijvoorbeeld de verzameling uitbreiden om een ​​methode toe te voegen die alleen specifieke games retourneert.

 var GamesCollection = Backbone.Collection.extend (model: Game, old: function () return this.filter (function (game) return game.get ('releaseDate') < 2009; );   );

Dat was makkelijk, toch? We controleren alleen of een game vóór 2009 is uitgebracht en zo ja, retourneer de game.

Je kunt de inhoud van een verzameling ook direct manipuleren zoals:

 var spellen = nieuwe GamesCollection games.get (0);

Met het bovenstaande fragment wordt een nieuwe verzameling geconverteerd en vervolgens wordt het model opgehaald met een ID van 0. U kunt een element op een specifieke positie vinden door naar de index te verwijzen naar de op methode zoals zo: games.at (0);

En tot slot kunt u uw verzameling dynamisch vullen zoals zo:

 var GamesCollection = Backbone.Collection.extend (model: Game, url: '/ games'); var spellen = nieuwe GamesCollection games.fetch ();

We laten Backbone gewoon waar de gegevens vandaan komen via de url eigendom. Met dat gedaan, zijn we slechts een nieuw object aan het creëren en het aanroepen van de halen methode waarmee een asynchrone aanroep naar de server wordt gestart en de verzameling met de resultaten wordt gevuld.

Dat zou de basisprincipes van collecties met Backbone moeten omvatten. Zoals ik al zei, zijn er hier heel veel goodies met Backbone die al heel wat handige hulpprogramma's uit de Underscore-bibliotheek bombarderen. Een snelle doorlezing van de officiële documentatie moet u op weg helpen.


Uitzicht

Aanzichten in Backbone kunnen op het eerste gezicht enigszins verwarrend zijn. Voor MVC-puristen lijken ze eerder op een controller dan op een weergave zelf.

Een weergave verwerkt twee taken fundamenteel:

  • Luister naar gebeurtenissen die door de DOM en modellen / collecties worden gegooid.
  • Vertegenwoordig de status en het gegevensmodel van de toepassing voor de gebruiker.

Laten we doorgaan en een heel eenvoudige weergave maken.

 GameView = Backbone.View.extend (tagName: "div", className: "game", render: function () // code voor het weergeven van de HTML voor de weergave);

Redelijk eenvoudig als je deze tutorial tot nu toe hebt gevolgd. Ik specificeer alleen welk HTML-element moet worden gebruikt om de weergave door de tagName attribuut, evenals de ID ervoor naam van de klasse.

Laten we verdergaan naar het renderinggedeelte.

 render: function () this.el.innerHTML = this.model.get ('name'); // Of de jQuery-weg $ (this.el) .html (this.model.get ('name')); 

el verwijst naar het DOM-element waarnaar in de weergave wordt verwezen. We hebben simpelweg toegang tot de naam van het spel voor de elementen innerHTML eigendom. Simpel gezegd, de div element bevat nu de naam van onze game. Het is duidelijk dat de manier van jQuery eenvoudiger is als je de bibliotheek eerder hebt gebruikt.

Met ingewikkeldere lay-outs is het omgaan met HTML in JavaScript niet alleen vervelend, maar ook roekeloos. In deze scenario's is sjablonen de juiste keuze.

Backbone wordt geleverd met een minimale sjabloonoplossing dankzij Underscore.JS, maar u bent van harte welkom om een ​​van de uitstekende template-oplossingen te gebruiken die beschikbaar zijn.

Laten we tot slot eens kijken hoe views luisteren naar gebeurtenissen. DOM-gebeurtenissen eerst.

 evenementen: 'klik. naam': 'handleClick', handleClick: function () alert ('In naam van de wetenschap, jij monster'); // Andere acties indien nodig

Moet eenvoudig genoeg zijn als je eerder met evenementen hebt gewerkt. We zijn in feite aan het definiëren en aan het aansluiten events door het object events. Zoals je hierboven kunt zien, verwijst het eerste deel naar het evenement, het volgende deel geeft de triggerelementen aan terwijl het laatste deel verwijst naar de functie die moet worden ontslagen.

En nu op binden aan modellen en collecties. Ik zal hier de binding aan modellen bespreken.

 GameView = Backbone.View.extend (initialize: function (args) _.bindAll (this, 'changeName'); this.model.bind ('change: name', this.changeName);,);

Het eerste dat opvalt, is hoe we de bindende code in de initialiseren functies. Uiteraard is het het beste om dit vanaf het begin te doen.

bindAll is een hulpprogramma van Underscore dat de waarde van een functie blijft behouden deze waarde. Dit is vooral handig omdat we een aantal functies doorgeven en functies die zijn opgegeven als callbacks hebben deze waarde gewist.

Nu wanneer een model is naam attribuut is gewijzigd, de naam veranderen functie wordt aangeroepen. U kunt ook gebruik maken van de toevoegen en verwijderen werkwoorden om te pollen voor veranderingen.

Luisteren naar wijzigingen in een verzameling is net zo eenvoudig als het vervangen model- met verzameling terwijl de handler aan de callback wordt gekoppeld.


controleur

Met controllers in Backbone kun je in essentie leesbare, stateful apps maken met hashbangs.

 var Hashbangs = Backbone.Controller.extend (routes: "! /": "root", "! / games": "games",, root: function () // Bereid de startpagina voor en render dingen , games: function () // Weergaven weergeven om een ​​verzameling boeken weer te geven,);

Dit is heel vertrouwd met routing in traditionele serverside MVC-frameworks. Bijvoorbeeld, !/spellen zal in kaart brengen naar de spellen functie terwijl de URL in de browser zelf is domein / #! / games.

Door middel van intelligent gebruik van hashbangs, kunt u apps maken die zwaar op JS zijn gebaseerd maar ook bladwijzerbaar zijn.

Als u zich zorgen maakt over het verbreken van de back-knop, heeft Backbone het ook.

 // Start de controller zoals zo var ApplicationController = nieuwe controller; Backbone.history.start ();

Met het bovenstaande fragment kan Backbone uw hashbangs controleren en in combinatie met de routes die u eerder hebt opgegeven, uw app bladwijzerbaar maken.


Wat ik heb geleerd van Backbone

Over het algemeen zijn hier enkele lessen die ik heb geleerd van de Backbone-manier om applicaties te maken:

  • We hebben echt MVC nodig voor de frontend. Traditionele methoden laten ons met code die te gekoppeld, rommelig en ongelooflijk moeilijk te onderhouden is.
  • Het opslaan van gegevens en status in de DOM is een slecht idee. Dit begon zinvoller te worden na het maken van apps waarbij verschillende delen van de app moesten worden bijgewerkt met dezelfde gegevens.
  • Vetmodellen en skinny controllers zijn de juiste keuze. Workflow wordt vereenvoudigd wanneer bedrijfslogica wordt verzorgd door modellen.
  • Templeren is een absolute noodzaak. HTML in je JavaScript plaatsen geeft je slecht karma.

Het is voldoende om te zeggen dat Backbone een paradigmaverschuiving heeft veroorzaakt in hoe front-ends moeten worden geconstrueerd, tenminste voor mij. Gezien de zeer brede reikwijdte van het artikel van vandaag, weet ik zeker dat je een hoop vragen hebt. Klik op de opmerkingen hieronder om te checken. Hartelijk bedankt voor het lezen en verwacht in de toekomst nog een heleboel Backbone-zelfstudies!