Verwenden Sie Backbone.js, um Interaktionen zu beschleunigen

Autor: Monica Porter
Erstelldatum: 13 Marsch 2021
Aktualisierungsdatum: 15 Kann 2024
Anonim
Linux-Tutorial für Anfänger
Video: Linux-Tutorial für Anfänger

Inhalt

Wenn Sie schnell ein kleines JavaScript-Tool erstellen möchten, denken Sie wahrscheinlich nicht an die Verwendung eines Frameworks. Es ist einfacher, jQuery-Code zusammen zu hacken, als ein neues Framework zu installieren und zu lernen, oder? Falsch, Backbone.js ist ein superleichtes Kleberahmenwerk, das genau wie das normale alte JavaScript aussieht, das Sie zum Schreiben verwendet haben.

Wir machen hier bei ZURB viele statische Prototypen, weil wir gerne durch Seiten klicken können, ohne Backend-Code schreiben zu müssen. Oft haben wir eintönige graue Platzhalterbilder eingefügt, oder manchmal haben wir Flickr nach Beispielbildern durchsucht, um zu visualisieren, was im endgültigen Entwurf enthalten sein könnte. Das war bis zu einem magischen Freitag, als wir beschlossen, dass es großartig wäre, JavaScript zu schreiben, um unsere Probleme zu lösen. Wir wollten in der Lage sein, Fotos auf Flickr direkt aus den Platzhalterbildern selbst zu suchen und auszuwählen. Wir würden es FlickrBomb nennen, und dies ist die Geschichte, wie wir es mit Backbone.js erstellt haben.


Es wird dringend empfohlen, vor dem Lesen einen kurzen Blick auf FlickrBomb zu werfen. Dies ist eine dieser Arten von Deals, bei denen ein Klick mehr als tausend Worte sagt. Mach weiter, wir warten.

Es gibt heutzutage viele JavaScript-Frameworks auf dem Block, SproutCore, JavaScriptMVC, Spine, Sammy, Knockout. Aber wir mochten Backbone.js für dieses spezielle Projekt aus verschiedenen Gründen:

1. Es ist leicht (100% fettfrei)

  • im Gewicht, mit der neuesten verpackten Version ist etwa 4,6 kb
  • Bei Code mit etwas mehr als 1.000 Codezeilen ist es nicht besonders schwierig, einer Stapelverfolgung bis in die Interna zu folgen, ohne den Verstand zu verlieren

2. Es sieht aus wie JavaScript

  • weil es JavaScript ist, ist es das und das ist alles
  • Es verwendet jQuery, das selbst Ihre Oma heutzutage kennt

3. Super einfache Ausdauer


  • Standardmäßig werden Daten in einem Backend (über REST) ​​gespeichert. Wenn Sie jedoch ein einzelnes Plug-In einfügen, werden diese stattdessen im lokalen Speicher gespeichert
  • Da die Persistenz-API abstrahiert wird, kann sie in einem REST-Backend beibehalten werden, indem nur das lokale Speicher-Plug-In entfernt wird

Dann fangen wir an

Da Backbone.js nur JavaScript ist, müssen wir es nur zusammen mit Underscore.js auf der Seite einfügen. jQuery ist keine harte Abhängigkeit für Backbone an sich, aber wir werden es verwenden, also werden wir es hier aufnehmen. Wir werden auch das lokale Speicher-Plug-In verknüpfen, da wir keine Probleme beim Einrichten eines Backends haben möchten. Beachten Sie, dass die Dateien hier der Einfachheit halber direkt verknüpft wurden, Sie jedoch immer Ihre eigenen Assets in der Produktion hosten sollten.

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>

Der gesamte folgende Code in diesem Artikel ist spezifisch für unsere Anwendung, sodass wir ihn in eine app.js-Datei aufnehmen oder einfach inline, wenn dies Ihr Ding ist. Denken Sie daran, es nach Backbone einzuschließen. Mit Backbone können Teile unserer Anwendung abstrahiert werden, um sie sowohl modular für eine einfache Wiederverwendung als auch für andere besser lesbar zu machen. Um diese Abstraktion am besten zu veranschaulichen, sollten wir das Design von FlickrBomb von unten nach oben erklären, beginnend mit den Modellen und endend mit den Ansichten.


Unser erstes Modell

Die erste Aufgabe, die wir angehen wollten, war das Abrufen der Fotos von Flickr. Das Modellieren eines FlickrImage im Backbone ist einfach genug. Wir erstellen ein neues Modell mit dem Namen FlickrImage und fügen einige Methoden hinzu, mit denen wir Daumen unterschiedlicher Größe erhalten können.

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 auf der längsten Seite case 'large ': size_code =' _b '; break; // 1024 auf der längsten Seite default: size_code =' ';} return "http: // farm" + this.get (' farm ') + ".static.flickr.com / "+ this.get ('server') +" / "+ this.get ('id') +" _ "+ this.get ('secret') + size_code +" .webp ";}})

Modelle in Backbone sind Objekte, die beibehalten werden können und mit denen einige Funktionen verknüpft sind, ähnlich wie Modelle in anderen MVC-Frameworks. Der magische Teil von Backbone-Modellen besteht darin, dass wir Ereignisse an Attribute binden können, sodass wir unsere Ansichten aktualisieren können, wenn sich dieses Attribut ändert, um dies widerzuspiegeln. Aber wir sind uns ein wenig voraus.

Wenn wir die Fotos von Flickr abrufen, erhalten wir genügend Informationen, um URLs für alle Größen zu erstellen. Da diese Assembly jedoch uns überlassen bleibt, haben wir die Funktion .image_url () implementiert, die einen Größenparameter verwendet und einen öffentlichen Link zurückgibt. Da dies ein Backbone-Modell ist, können wir this.get () verwenden, um auf Attribute des Modells zuzugreifen. Mit diesem Modell können wir also an anderer Stelle im Code Folgendes tun, um die URL eines Flickr-Bildes abzurufen.

flickrImage.image_url ("groß")

Ziemlich prägnant, was? Da dieses Modell für unsere Anwendung spezifisch ist, werden wir einige Wrapper-Funktionen für die Bildgrößen in Vollgröße und Daumen hinzufügen.

Eine Sammlung von Bildern

FlickrBomb befasst sich mit Sammlungen von Bildern, nicht mit Einzelbildern, und Backbone bietet eine bequeme Möglichkeit, dies zu modellieren. Die treffend benannte Sammlung wird verwendet, um Flickr-Bilder für einen einzelnen Platzhalter zu gruppieren.

var FlickrImages = Backbone.Collection.extend ({Modell: FlickrImage, Schlüssel: flickrbombAPIkey, Seite: 1, Abruf: Funktion (Schlüsselwörter, Erfolg) {var self = this; Erfolg = Erfolg || $ .noop; this.keywords = Schlüsselwörter || this.keywords; $ .ajax ({url: 'http://api.flickr.com/services/rest/', Daten: {api_key: self.key, Format: 'json', Methode: 'flickr. photos.search ', tags: this.keywords, per_page: 9, page: this.page, Lizenz: flickrbombLicenseTypes}, Datentyp:' jsonp ', jsonp:' jsoncallback ', Erfolg: Funktion (Antwort) {self.add (Antwort .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);}});

Hier gibt es ein paar Dinge zu beachten. Zunächst einmal die Modell- Das Attribut teilt den Sammlungen mit, welche Art von Modell erfasst wird. Wir haben auch einige Attribute, die wir für die spätere Verwendung initialisiert haben: key ist unser Flickr-API-Schlüssel. Sie möchten flickrbombAPIkey durch die Zeichenfolge Ihres eigenen Flickr-API-Schlüssels ersetzen. Das Abrufen eines Flickr-API-Schlüssels ist kostenlos und einfach. Folgen Sie einfach diesem Link: www.flickr.com/services/api/misc.api_keys.html. Das Seitenattribut ist die aktuelle Seite der Flickr-Fotos, auf denen wir uns befinden.

Die große Methode hier ist .fetch (), die die Details des Abrufs von Fotos aus der Flickr-API abstrahiert. Um Probleme mit domänenübergreifenden Anforderungen zu vermeiden, verwenden wir JSONP, das sowohl von der Flickr-API als auch von jQuery unterstützt wird. Die anderen Parameter, die wir an die API übergeben, sollten selbsterklärend sein. Von besonderem Interesse sind die hier aufgerufenen Backbone-Funktionen. Im erfolgreichen Rückruf verwenden wir .add (), eine Funktion, die ein Array von Modellattributen verwendet, Modellinstanzen aus diesen Attributen erstellt und sie dann der Auflistung hinzufügt.

Die Funktionen .nextPage () und .prevPage () ändern zuerst die Seite, die angezeigt werden soll.
Verwenden Sie die Erfassungsfunktion .remove (), um alle vorhandenen Modelle aus dem zu entfernen
Sammlung, und rufen Sie dann fetch auf, um die Fotos für die aktuelle Seite zu erhalten (die wir gerade
geändert).

Das FlickrBombImage

Auf dem Weg nach oben benötigen wir ein weiteres Modell, um das Platzhalterbild darzustellen, das aus einer Sammlung von FlickrImages und dem aktuell ausgewählten FlickrImage besteht. Wir nennen dieses Modell FlickrBombImage.

var localStorage = (unterstützt_local_storage ())? neuer Speicher ("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: function () {this.save ();}, loadFirstImage: function () {if (this.get ('src') === undefined) {this.set ({src: this.flickrImages. first (). image_url ()});}}});

Da dieses Modell dafür verantwortlich ist, das aktuell ausgewählte Bild zwischen den Seitenladevorgängen zu verfolgen, muss es wissen, welcher Localstorage-Speicher verwendet werden soll.In der ersten Zeile wird sichergestellt, dass localstorage unterstützt wird, und anschließend wird der Speicher erstellt, in dem das ausgewählte Bild beibehalten wird.

Mit Backbone können wir eine .initialize () -Funktion definieren, die beim Erstellen einer Instanz des Modells aufgerufen wird. Wir verwenden diese Funktion in FlickrBombImage, um eine neue Instanz der FlickrImages-Auflistung zu erstellen, die für dieses Bild verwendeten Schlüsselwörter weiterzugeben und die Bilder dann von Flickr abzurufen.

Die Funktion .loadFirstImage () wurde als Rückruf übergeben, der ausgeführt wird, wenn die Bilder von Flickr geladen wurden. Wie Sie wahrscheinlich erraten können, legt diese Funktion fest, dass das aktuelle Bild das erste in der Sammlung von Flickr ist. Dies ist nicht der Fall, wenn das aktuelle Bild bereits festgelegt wurde.

Wir werden auch die Attribut-Rückrufe von Backbone verwenden, um unsere .changeSrc () -Funktion auszulösen, wenn sich das src-Attribut dieses Modells ändert. Alles, was dieser Rückruf bewirkt, ist der Aufruf von .save (), einer Backbone-Modellfunktion, die die Attribute des Modells für jede implementierte Speicherebene (in unserem Fall localstore) beibehält. Auf diese Weise bleibt das ausgewählte Bild sofort erhalten, wenn es geändert wird.

Die Ansichtsebene

Nachdem wir den gesamten Backend-Code (also das Frontend-Backend) geschrieben haben, können wir die Ansichten zusammenstellen. Ansichten in Backbone unterscheiden sich ein wenig von Ansichten in anderen herkömmlichen MVC-Frameworks. Während sich eine Ansicht normalerweise nur mit der Präsentation befasst, ist eine Backbone-Ansicht auch für das Verhalten verantwortlich. Das bedeutet, dass Ihre Ansicht nicht nur definiert, wie etwas aussieht, sondern auch, was es bei der Interaktion tun soll.

Eine Ansicht ist normalerweise (aber nicht immer) an einige Daten gebunden und durchläuft drei Phasen, um aus diesen Daten ein Präsentations-Markup zu generieren:

1. Das View-Objekt wird initialisiert und ein leeres Element erstellt.
2. Die Renderfunktion wird aufgerufen und generiert das Markup für die Ansicht, indem es in das im vorherigen Schritt erstellte Element eingefügt wird.
3. Das Element ist an das DOM angehängt.

Dies scheint eine Menge Arbeit zu sein, um ein Markup zu generieren, und wir sind noch nicht einmal beim Verhaltensteil der Ansicht, aber es ist wichtig, und hier ist der Grund dafür. Jedes Mal, wenn Sie Elemente im DOM ändern, lösen Sie einen sogenannten Browser-Reflow aus. Ein Reflow ist der Browser, der neu positioniert, wie alles auf der Seite positioniert ist. Browser-Reflows können die Leistung beeinträchtigen, wenn sie innerhalb eines Drag- oder Resize-Ereignisses aufgerufen werden, das in sehr kurzen Intervallen ausgelöst wird. Schlimmer noch, sie sehen schlampig aus. Bei der komplexen Seitenmanipulation können Sie tatsächlich sehen, wie Elemente zur Seite hinzugefügt und die Elemente neu positioniert werden. Wenn Sie dem Backbone-Muster zum Initialisieren, Rendern und Anhängen folgen, garantieren Sie einen einzelnen Reflow, und die Änderungen an der Seite werden unabhängig von der Komplexität der Elementmanipulation sofort wahrgenommen.

Die 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 (dies,' 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);}, events: { "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;}, ...});

Die Funktionen dieser Ansicht wurden der Kürze halber weggelassen. Der gesamte Quellcode ist auf GitHub verfügbar: github.com/zurb/flickrbomb

Oben in der Ansicht befinden sich einige Backbone-spezifische Attribute. tagName und className werden verwendet, um das Tag und die Klasse zu definieren, die auf das Element dieser Ansicht angewendet werden. Denken Sie daran, dass in Schritt eins der Ansichtserstellung ein Objekt erstellt wird. Da diese Erstellung von Backbone ausgeführt wird, müssen Sie das Element und die Klasse angeben. Beachten Sie, dass das Backbone sinnvolle Standardeinstellungen hat. Wenn wir diese Attribute weglassen, wird standardmäßig ein div verwendet, und es wird keine Klasse angewendet, es sei denn, Sie geben eine an.

Das Template-Attribut ist eine Konvention, aber nicht erforderlich. Wir verwenden es hier, um die JavaScript-Vorlagenfunktion anzugeben, mit der wir unser Markup für diese Ansicht generieren. Wir verwenden die in Underscore.js enthaltene Funktion _.template (), aber Sie können die von Ihnen bevorzugte Template-Engine verwenden, wir werden Sie nicht beurteilen.

In unserer .initialize () -Funktion ziehen wir die Schlüsselwortzeichenfolge aus dem Bild-Tag heraus und erstellen dann mit diesen Schlüsselwörtern ein FlickrBombImage-Modell. Wir binden auch die Funktion .addImage (), die ausgeführt werden soll, wenn der FlickrImages-Auflistung ein FlickrImage hinzugefügt wird. Diese Funktion hängt das neu hinzugefügte FlickrImage an unser Flyout zur Bildauswahl an. Die letzte und wichtigste Zeile bindet die Funktion .updateSrc () an das Auslösen, wenn das aktuell ausgewählte FlickrImage geändert wird. Wenn das aktuelle Bild im Modell geändert wird, wird diese Funktion ausgeführt, das src-Attribut des Bildelements aktualisiert und die CSS-Größe geändert und das Bild so zugeschnitten, dass es in die vom Benutzer angegebenen Bildabmessungen passt.

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

Nach .initialize () haben wir den Verhaltensteil der Ansicht. Backbone bietet eine bequeme Möglichkeit, Ereignisse mithilfe eines Ereignisobjekts zu binden. Das Ereignisobjekt verwendet die Methode jQuery .delegate (), um die eigentliche Bindung an das View-Element durchzuführen, sodass unabhängig davon, welche Manipulation Sie an dem Element in der Ansicht vornehmen, alle gebundenen Ereignisse weiterhin funktionieren. Es funktioniert genau wie jQuery .live (), außer dass Sie Ereignisse nicht an das gesamte Dokument binden, sondern im Rahmen eines beliebigen Elements binden können. Der Schlüssel jedes Eintrags im Ereignisobjekt besteht aus dem Ereignis und dem Selektor. Der Wert gibt die Funktion an, die an dieses Ereignis gebunden werden soll. Beachten Sie, dass .delegate () bei einigen Ereignissen wie submit nicht funktioniert. Eine vollständige Liste der unterstützten Ereignisse finden Sie in der Dokumentation zu jQuery .live ().

render: function () {$ (this.el) .html (this.template ()); this.image.fetch (); this.resize (); gib das zurück;}

Zuletzt haben wir die Funktion .render (), die für das Erstellen unseres Markups und das Ausführen zusätzlicher Arbeiten verantwortlich ist, die erst ausgeführt werden können, wenn das View-Markup dem View-Element hinzugefügt wurde. Nachdem wir unsere Vorlage gerendert haben, müssen wir .fetch () auf unserem FlickrBombImage aufrufen. .fetch () ist eine Backbone-Funktion, die die neueste Kopie des Modells von der Persistenzschicht abruft. Wenn wir dieses Modell zuvor gespeichert hätten, würde .fetch () diese Daten jetzt abrufen. Nachdem das Bild abgerufen wurde, müssen wir die Größenänderung aufrufen, um es richtig zu positionieren.

Die Heimstrecke

Nachdem alle Teile vorhanden sind, müssen wir nur noch die Platzhalterbilder auf der Seite finden und durch die gerenderten FlickrBombImage-Ansichten ersetzen.

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

Dieser kleine Ausschnitt muss am Ende der Seite oder in einem dokumentenbereiten Rückruf ausgeführt werden, um sicherzustellen, dass er die Platzhalterbilder findet, die er ersetzen wird. Wir verwenden die Konvention, flickr: // [KEYWORD] im src-Attribut eines Bild-Tags anzugeben, um anzugeben, dass es mit Bildern von Flickr gefüllt werden soll. Wir finden Bildelemente mit einem passenden src-Attribut, erstellen eine neue FlickrBombImageView und ersetzen das Bild durch unser. Wir nehmen eine Kopie des Originalbilds und übergeben sie an FlickrBombView, damit wir einige zusätzliche Konfigurationsoptionen abrufen können, die möglicherweise für das Element angegeben wurden.

Das Endergebnis all dieser harten Arbeit ist eine sehr einfache API für Benutzer der Bibliothek. Sie können einfach Bild-Tags mithilfe der flickr: // -Konvention definieren, den FlickrBomb-Code am Ende ihrer Seite ablegen und bam, sie haben Platzhalterbilder von Flickr.

Funktioniert auch hervorragend mit großen alten Web-Apps

Wir haben eine große alte Web-App namens Notable, die ohne Bedenken für die clientseitige Generierung von Inhalten geschrieben wurde. Als wir Teile der App durch Generieren von Content-Clients aufladen wollten, haben wir uns für Backbone entschieden. Die Gründe waren dieselben: Wir wollten ein leichtes Framework, um den Code besser organisieren zu können, aber nicht, um die gesamte Anwendung zu überdenken.

Wir haben die Änderungen Anfang dieses Jahres mit großem Erfolg eingeführt und seitdem Backbones-Lob gesungen.

Zusätzliche Ressourcen

Backbone bietet viel mehr als das, was ich in diesem Artikel behandelt habe, den C-Teil (Controller) von MVC (Model View Controller) für den Anfang, der in der neuesten Version tatsächlich ein R (Router) ist. Und alles wird in der Backbone-Dokumentation behandelt, die an einem leichten Samstagmorgen gelesen wurde:
documentcloud.github.com/backbone/

Wenn Sie traditionellere Tutorials bevorzugen, lesen Sie den sehr gut dokumentierten Code dieser in Backbone geschriebenen ToDo-Anwendung:
documentcloud.github.com/backbone/docs/todos.html

Beliebt