Einzelseiten-ToDo-Anwendung mit Backbone.js

Backbone.js ist ein JavaScript-Framework zum Erstellen flexibler Webanwendungen. Es gibt Modelle, Sammlungen, Ansichten, Ereignisse, Router und einige andere großartige Funktionen. In diesem Artikel werden wir eine einfache ToDo-Anwendung entwickeln, die das Hinzufügen, Bearbeiten und Entfernen von Aufgaben unterstützt. Wir sollten auch eine Aufgabe als kennzeichnen können erledigt und archivieren. Um die Länge dieses Beitrags angemessen zu halten, wird keine Kommunikation mit einer Datenbank aufgenommen. Alle Daten werden auf der Clientseite aufbewahrt.

Konfiguration

Hier ist die Dateistruktur, die wir verwenden werden:

css └── styles.css js └── Kollektionen └── ToDos.js └── Modelle └── ToDo.js └── Hersteller └── backbone.js jquery-1.10.2.min.js Ers underscore.js └── Ansichten └── App.js └── index.html 

Es gibt wenige Dinge, die offensichtlich sind /css/styles.css und /index.html. Sie enthalten die CSS-Stile und das HTML-Markup. Im Zusammenhang mit Backbone.js ist das Modell ein Ort, an dem wir unsere Daten aufbewahren. Unsere ToDos werden also einfach nur Modelle sein. Und weil wir mehr als eine Aufgabe haben werden, werden wir sie in einer Sammlung organisieren. Die Geschäftslogik wird zwischen den Ansichten und der Datei der Hauptanwendung verteilt, App.js. Backbone.js hat nur eine harte Abhängigkeit - Underscore.js. Das Framework spielt auch sehr gut mit jQuery, also gehen beide auf die Verkäufer Verzeichnis. Jetzt brauchen wir nur noch ein kleines HTML-Markup und wir sind bereit zu gehen.

   Meine TODOs    

Wie Sie sehen, fügen wir alle externen JavaScript-Dateien nach unten hinzu, da dies am Ende des body-Tags eine gute Praxis ist. Wir bereiten auch das Bootstrapping der Anwendung vor. Es gibt einen Container für den Inhalt, ein Menü und einen Titel. Die Hauptnavigation ist ein statisches Element und wir werden es nicht ändern. Wir ersetzen den Inhalt des Titels und des div darunter.

Planen der Anwendung

Es ist immer gut, einen Plan zu haben, bevor wir an etwas arbeiten. Backbone.js hat keine sehr strenge Architektur, der wir folgen müssen. Das ist einer der Vorteile des Frameworks. Bevor wir mit der Implementierung der Geschäftslogik beginnen, wollen wir über die Basis sprechen.

Namensraum

Es empfiehlt sich, Ihren Code in einen eigenen Bereich zu stellen. Das Registrieren globaler Variablen oder Funktionen ist keine gute Idee. Was wir erstellen werden, sind ein Modell, eine Sammlung, ein Router und einige Ansichten von Backbone.js. Alle diese Elemente sollten in einem privaten Bereich leben. App.js wird die Klasse enthalten, die alles enthält.

// App.js var app = (Funktion () var api = Ansichten: , Modelle: , Sammlungen: , Inhalt: Null, Router: Null, Todos: Null, Init: Funktion ()  this.content = $ ("# content");, changeContent: function (el) this.content.empty (). append (el); dies zurückgeben;, title: function (str) $ ("h1 ") .text (str); zurückgeben;; var ViewsFactory = ; var Router = Backbone.Router.extend (); api.router = neuer Router (); return api;) (); 

Oben ist eine typische Implementierung des aufschlussreichen Modulmusters dargestellt. Das api Variable ist das Objekt, das zurückgegeben wird und die öffentlichen Methoden der Klasse darstellt. Das Ansichten, Modelle und Sammlungen Eigenschaften fungieren als Inhaber für die von Backbone.js zurückgegebenen Klassen. Das Inhalt ist ein jQuery-Element, das auf den Schnittstellencontainer des Hauptbenutzers verweist. Hier gibt es zwei Hilfsmethoden. Der erste aktualisiert diesen Container. Der zweite setzt den Titel der Seite. Dann haben wir ein Modul definiert ViewsFactory. Es wird unsere Ansichten liefern und am Ende haben wir den Router erstellt.

Sie fragen sich vielleicht, warum brauchen wir eine Fabrik für die Ansichten? Nun, es gibt einige gängige Muster bei der Arbeit mit Backbone.js. Eine davon bezieht sich auf die Erstellung und Verwendung der Ansichten.

var ViewClass = Backbone.View.extend (/ * logic here * /); var view = new ViewClass (); 

Es ist gut, die Ansichten nur einmal zu initialisieren und am Leben zu lassen. Sobald die Daten geändert wurden, rufen wir normalerweise Methoden der Ansicht auf und aktualisieren den Inhalt der Ansicht el Objekt. Der andere sehr beliebte Ansatz besteht darin, die gesamte Ansicht neu zu erstellen oder das gesamte DOM-Element zu ersetzen. Das ist jedoch aus Sicht der Leistung nicht wirklich gut. Daher erhalten wir normalerweise eine Dienstprogrammklasse, die eine Instanz der Ansicht erstellt und bei Bedarf zurückgibt.

Komponenten-Definition

Wir haben einen Namespace und können nun mit dem Erstellen von Komponenten beginnen. So sieht das Hauptmenü aus:

// views / menu.js app.views.menu = Backbone.View.extend (initialize: function () , render: function () ); 

Wir haben eine Eigenschaft namens erstellt Speisekarte das hält die Klasse der Navigation. Später können wir im Factory-Modul eine Methode hinzufügen, die eine Instanz davon erstellt.

var ViewsFactory = menu: function () if (! this.menuView) this.menuView = new api.views.menu (el: $ ("# menu"));  return this.menuView; ; 

Oben werden wir mit allen Ansichten umgehen und es wird sichergestellt, dass wir nur eine und dieselbe Instanz erhalten. Diese Technik funktioniert in den meisten Fällen gut.

Fließen

Der Einstiegspunkt der App ist App.js und sein drin Methode. Das nennen wir im onload Handler der Fenster Objekt.

window.onload = function () app.init ();  

Danach übernimmt der definierte Router die Kontrolle. Anhand der URL entscheidet er, welcher Handler ausgeführt werden soll. In Backbone.js haben wir nicht die übliche Model-View-Controller-Architektur. Der Controller fehlt und der größte Teil der Logik wird in die Ansichten eingefügt. Stattdessen verbinden wir die Modelle direkt mit Methoden in den Ansichten und erhalten sofort eine Aktualisierung der Benutzeroberfläche, sobald sich die Daten geändert haben.

Verwalten der Daten

Das Wichtigste in unserem kleinen Projekt sind die Daten. Unsere Aufgaben sollten wir bewältigen, also fangen wir von dort an an. Hier ist unsere Modelldefinition.

// models / ToDo.js app.models.ToDo = Backbone.Model.extend (Standardwerte: Titel: "ToDo", archiviert: false, done: false); 

Nur drei Felder. Die erste enthält den Text der Aufgabe und die beiden anderen sind Flags, die den Status des Datensatzes definieren.

Jedes Element innerhalb des Frameworks ist eigentlich ein Event-Dispatcher. Und da das Modell mit Setters geändert wird, weiß das Framework, wann die Daten aktualisiert werden, und kann den Rest des Systems darüber informieren. Sobald Sie etwas an diese Benachrichtigungen gebunden haben, reagiert Ihre Anwendung auf die Änderungen im Modell. Dies ist eine sehr leistungsfähige Funktion in Backbone.js.

Wie ich anfangs sagte, werden wir viele Datensätze haben und diese in einer Sammlung organisieren ToDos.

// Collections / ToDos.js app.collections.ToDos = Backbone.Collection.extend (initialize: function () this.add (title: "JavaScript-Grundkenntnisse lernen"); this.add (title: "Go to backbonejs.org "); this.add (title:" Entwickeln einer Backbone-Anwendung ");, model: app.models.ToDo up: function (index) if (index> 0) var tmp = this.models [index-1]; this.models [index-1] = this.models [index]; this.models [index] = tmp; this.trigger ("change");, down: function ( index) if (index < this.models.length-1)  var tmp = this.models[index+1]; this.models[index+1] = this.models[index]; this.models[index] = tmp; this.trigger("change");  , archive: function(archived, index)  this.models[index].set("archived", archived); , changeStatus: function(done, index)  this.models[index].set("done", done);  ); 

Das initialisieren Methode ist der Einstiegspunkt der Sammlung. In unserem Fall haben wir standardmäßig einige Aufgaben hinzugefügt. Natürlich stammen die Informationen in der realen Welt aus einer Datenbank oder einem anderen Ort. Aber um Sie auf dem Laufenden zu halten, machen wir das manuell. Das andere, was für Sammlungen typisch ist, ist die Einstellung Modell- Eigentum. Sie teilt der Klasse mit, welche Art von Daten gespeichert werden. Die restlichen Methoden implementieren eine benutzerdefinierte Logik, die sich auf die Funktionen in unserer Anwendung bezieht. oben und Nieder Funktionen ändern die Reihenfolge der ToDos. Zur Vereinfachung identifizieren wir jede Aufgabe mit einem Index im Array der Sammlung. Das heißt, wenn wir einen bestimmten Datensatz abrufen möchten, sollten wir auf seinen Index zeigen. Die Reihenfolge besteht also darin, die Elemente in einem Array zu wechseln. Wie Sie aus dem obigen Code erraten können, diese.Modelle ist das Array, über das wir sprechen. Archiv und Status ändern Eigenschaften des gegebenen Elements setzen. Wir setzen diese Methoden hier ein, weil die Ansichten Zugriff auf die ToDos Sammlung und nicht zu den Aufgaben direkt.

Außerdem müssen wir keine Modelle aus dem erstellen app.models.ToDo Klasse, aber wir müssen eine Instanz aus der erstellen app.collections.tooDos Sammlung.

// App.js init: function () this.content = $ ("# content"); this.todos = neue api.collections.ToDos (); kehre das zurück;  

Erste Ansicht anzeigen (Hauptnavigation)

Das erste, was wir zeigen müssen, ist die Navigation der Hauptanwendung.

// views / menu.js app.views.menu = Backbone.View.extend (template: _.template ($ ("# tpl-menu"). html ()), initialize: function () this.render ();, render: function () this. $ el.html (this.template ());; 

Es sind nur neun Zeilen Code, aber hier passiert viel cooles. Der erste legt eine Vorlage fest. Wenn Sie sich erinnern, haben wir Underscore.js zu unserer App hinzugefügt. Wir werden seine Templating Engine verwenden, weil sie gut funktioniert und einfach zu bedienen ist.

_.template (templateString, [Daten], [Einstellungen]) 

Was Sie am Ende haben, ist eine Funktion, die ein Objekt akzeptiert, das Ihre Informationen in Schlüsselwertpaaren und die templateString ist HTML-Markup. Ok, also akzeptiert es einen HTML-String, aber was ist $ ("# tpl-menu"). html () da machen? Wenn wir eine kleine Einzelseitenanwendung entwickeln, fügen wir die Vorlagen normalerweise wie folgt direkt in die Seite ein:

// index.html  

Und weil es sich um ein Skript-Tag handelt, wird es dem Benutzer nicht angezeigt. Aus einem anderen Blickwinkel ist dies ein gültiger DOM-Knoten, sodass wir den Inhalt mit jQuery erhalten könnten. Das obige kurze Snippet nimmt also nur den Inhalt dieses Script-Tags.

Das machen Methode ist in Backbone.js sehr wichtig. Das ist die Funktion, die die Daten anzeigt. Normalerweise binden Sie die von den Modellen ausgelösten Ereignisse direkt an diese Methode. Für das Hauptmenü benötigen wir jedoch kein solches Verhalten.

this. $ el.html (this.template ()); 

das. $ el ist ein Objekt, das vom Framework erstellt wird, und in jeder Ansicht ist es standardmäßig vorhanden (es gibt ein $ vor el weil wir jQuery enthalten haben). Und standardmäßig ist es leer

. Natürlich können Sie das mit dem ändern Verlinke den Namen Eigentum. Wichtiger ist jedoch, dass wir diesem Objekt keinen Wert direkt zuweisen. Wir ändern es nicht, wir ändern nur den Inhalt. Es gibt einen großen Unterschied zwischen der obigen und der nächsten Zeile:

this. $ el = $ (this.template ()); 

Der Punkt ist, wenn Sie die Änderungen im Browser sehen möchten, sollten Sie vorher die Render-Methode aufrufen, um die Ansicht an das DOM anzuhängen. Andernfalls wird nur das leere Div angehängt. Es gibt auch ein anderes Szenario, in dem Sie verschachtelte Ansichten haben. Da Sie die Eigenschaft direkt ändern, wird die übergeordnete Komponente nicht aktualisiert. Die gebundenen Ereignisse sind möglicherweise ebenfalls defekt und Sie müssen die Listener erneut anschließen. Sie sollten also wirklich nur den Inhalt von ändern das. $ el und nicht der Wert der Immobilie.

Die Ansicht ist jetzt fertig und wir müssen sie initialisieren. Fügen wir es unserem Factory-Modul hinzu:

// App.js var ViewsFactory = menu: function () if (! This.menuView) this.menuView = new api.views.menu (el: $ ("# menu"));  return this.menuView; ; 

Am Ende rufen Sie einfach die Speisekarte Methode im Bootstrapping-Bereich:

// App.js init: function () this.content = $ ("# content"); this.todos = neue api.collections.ToDos (); ViewsFactory.menu (); kehre das zurück;  

Beachten Sie, dass beim Erstellen einer neuen Instanz aus der Navigationsklasse ein bereits vorhandenes DOM-Element übergeben wird $ ("# menu"). Also die das. $ el Eigenschaft in der Ansicht zeigt tatsächlich auf $ ("# menu").

Routen hinzufügen

Backbone.js unterstützt das Push-Zustand Operationen. Mit anderen Worten, Sie können die URL des aktuellen Browsers bearbeiten und zwischen den Seiten wechseln. Wir bleiben jedoch beispielsweise bei den guten alten Hash-URLs / # edit / 3.

// App.js var Router = Backbone.Router.extend (routen: "archivieren": "archivieren", "neu": "newToDo", "edit /: index": "editToDo", "delete /: index" ":" delteToDo "," ":" list ", Liste: Funktion (Archiv) , Archiv: Funktion () , NewToDo: Funktion () , EditToDo: Funktion (Index) , DelteToDo: Funktion (Index) ); 

Oben ist unser Router. In einem Hash-Objekt sind fünf Routen definiert. Der Schlüssel wird in die Adressleiste des Browsers eingegeben, und der Wert ist die Funktion, die aufgerufen wird. Beachten Sie, dass es gibt :Index auf zwei der Routen. Dies ist die Syntax, die Sie verwenden müssen, wenn Sie dynamische URLs unterstützen möchten. In unserem Fall, wenn Sie schreiben # edit / 3 das editToDo wird mit Parameter ausgeführt Index = 3. Die letzte Zeile enthält eine leere Zeichenfolge, dh sie behandelt die Startseite unserer Anwendung.

Anzeigen einer Liste aller Aufgaben

Was wir bisher gebaut haben, ist die Hauptansicht für unser Projekt. Die Daten werden aus der Sammlung abgerufen und auf dem Bildschirm ausgedruckt. Wir könnten dieselbe Ansicht für zwei Dinge verwenden - alle aktiven ToDos und die archivierten anzeigen.

Bevor Sie mit der Implementierung der Listensicht fortfahren, sehen Sie, wie sie tatsächlich initialisiert wird.

// in App.js-Ansichten Werksliste: function () if (! this.listView) this.listView = new api.views.list (model: api.todos);  zurückgeben this.listView;  

Beachten Sie, dass wir die Sammlung übergeben. Das ist wichtig, weil wir es später verwenden werden dieses Model auf die gespeicherten Daten zugreifen. Die Factory gibt unsere Listenansicht zurück, aber der Router ist der Typ, der sie der Seite hinzufügen muss.

// in der Routerliste von App.js: function (archive) var view = ViewsFactory.list (); api .title (Archiv? "Archiv:": "Ihre ToDos:") .changeContent (Ansicht. $ el); view.setMode (Archiv? "Archiv": Null) .render ();  

Vorerst die Methode Liste im Router wird ohne Parameter aufgerufen. Die Sicht ist also nicht in Archiv Im Modus werden nur die aktiven ToDos angezeigt.

// views / list.js app.views.list = Backbone.View.extend (mode: null, events: , initialize: function () var handler = _.bind (this.render, this); this .model.bind ('change', handler); this.model.bind ('add', handler); this.model.bind ('remove', handler);, render: function () , priorityUp: Funktion (e) , PrioritätDown: Funktion (E) , Archiv: Funktion (E) , ChangeStatus: Funktion (E) , SetMode: Funktion (Modus) this.mode = Modus; zurückgeben; ); 

Das Modus Diese Eigenschaft wird während des Renderns verwendet. Wenn sein Wert ist mode = "Archiv" dann werden nur die archivierten ToDos angezeigt. Das Veranstaltungen ist ein Objekt, das wir sofort füllen werden. Dies ist der Ort, an dem wir die DOM-Ereigniszuordnung platzieren. Die restlichen Methoden sind Antworten der Benutzerinteraktion und sie sind direkt mit den benötigten Funktionen verknüpft. Zum Beispiel, priorityUp und priorityDown ändert die Reihenfolge der ToDos. Archiv verschiebt den Artikel in den Archivbereich. Status ändern markiert das ToDo einfach als erledigt.

Es ist interessant, was im Inneren passiert initialisieren Methode. Früher haben wir gesagt, dass Sie normalerweise die Änderungen im Modell (in unserem Fall die Sammlung) an das Modul binden werden machen Methode der Ansicht. Sie können eingeben this.model.bind ('change', this.render). Aber schon bald werden Sie feststellen, dass die diese Stichwort in der machen Die Methode zeigt nicht auf die Ansicht selbst. Das liegt daran, dass der Geltungsbereich geändert wird. Als Problemumgehung erstellen wir einen Handler mit einem bereits definierten Bereich. Underscore ist das binden Funktion wird für verwendet.

Und hier ist die Umsetzung der machen Methode.

// views / list.js render: function () ) var html = '
    ', self = this; this.model.each (function (todo, index) if (self.mode === "archivieren"? todo.get ("archiviert") === true: todo.get ("archiviert") === false ) var template = _.template ($ ("# tpl-list-item"). html ()); html + = template (title: todo.get ("title")), index: index, archiveLink: self .mode === "Archiv"? "Nicht archivieren": "Archiv", erledigt: todo.get ("done")? "ja": "nein", doneChecked: todo.get ("done")? 'checked = = "geprüft" ': "");); html + = '
'; dies. $ el.html (html); this.delegateEvents (); kehre das zurück;

Wir durchlaufen alle Modelle in der Sammlung und generieren eine HTML-Zeichenfolge, die später in das DOM-Element der Ansicht eingefügt wird. Es gibt wenige Prüfungen, die die ToDos von archiviert zu aktiv unterscheiden. Die Aufgabe ist als gekennzeichnet erledigt mit Hilfe einer Checkbox. Um dies zu zeigen, müssen wir ein geprüft == "geprüft" Attribut zu diesem Element. Sie stellen möglicherweise fest, dass wir verwenden this.delegateEvents (). In unserem Fall ist dies notwendig, weil wir die Sicht vom DOM trennen und anfügen. Ja, wir ersetzen das Hauptelement nicht, aber die Handler der Ereignisse werden entfernt. Deshalb müssen wir Backbone.js mitteilen, dass sie sie erneut anhängen sollen. Die im obigen Code verwendete Vorlage lautet:

// index.html  

Beachten Sie, dass eine definierte CSS-Klasse definiert ist fertig-ja, was das ToDo mit einem grünen Hintergrund malt. Daneben gibt es eine Reihe von Links, mit denen wir die benötigte Funktionalität implementieren. Sie haben alle Datenattribute. Der Hauptknoten des Elements, li, hat Datenindex. Der Wert dieses Attributs zeigt den Index der Aufgabe in der Auflistung an. Beachten Sie, dass die speziellen Ausdrücke eingeschlossen sind <%=… %> werden an die gesendet Vorlage Funktion. Das sind die Daten, die in die Vorlage eingefügt werden.

Es ist Zeit, der Ansicht einige Ereignisse hinzuzufügen.

// views / list.js events: 'Klicken Sie auf [data-up]': 'priorityUp' ',' klicken Sie auf [data-down] ':' priorityDown ',' klicken Sie auf ein Archiv [data-archive] ':' ',' klicken Sie auf die Eingabe [Datenstatus] ':' changeStatus ' 

In Backbone.js ist die Definition des Ereignisses nur ein Hash. Sie geben zuerst den Namen des Ereignisses und dann einen Selektor ein. Die Werte der Eigenschaften sind eigentlich Methoden der Ansicht.

// views / list.js priorityUp: Funktion (e) var index = parseInt (e.target.parentNode.parentNode.getAttribute ("data-index")); this.model.up (index); , priorityDown: function (e) var index = parseInt (e.target.parentNode.parentNode.getAttribute ("data-index")); this.model.down (index); , Archiv: Funktion (e) var index = parseInt (e.target.parentNode.parentNode.getAttribute ("data-index")); this.model.archive (this.mode! == "Archiv", Index); , changeStatus: function (e) var index = parseInt (e.target.parentNode.parentNode.getAttribute ("data-index")); this.model.changeStatus (e.target.checked, index);  

Hier benutzen wir e.target zum Handler kommen. Es zeigt auf das DOM-Element, das das Ereignis ausgelöst hat. Wir erhalten den Index der angeklickten Aufgabe und aktualisieren das Modell in der Sammlung. Mit diesen vier Funktionen haben wir unsere Klasse beendet und nun werden die Daten auf der Seite angezeigt.

Wie bereits erwähnt, werden wir dieselbe Ansicht für die Archiv Seite.

Liste: Funktion (Archiv) var view = ViewsFactory.list (); api .title (Archiv? "Archiv:": "Ihre ToDos:") .changeContent (Ansicht. $ el); view.setMode (Archiv? "Archiv": Null) .render (); , Archiv: Funktion () this.list (true);  

Oben ist derselbe Routen-Handler wie zuvor, diesmal jedoch mit wahr als Parameter.

Hinzufügen und Bearbeiten von ToDos

Nach der Grundierung der Listenansicht können Sie eine weitere erstellen, die ein Formular zum Hinzufügen und Bearbeiten von Aufgaben enthält. So wird diese neue Klasse erstellt:

// App.js / views factory form: function () if (! This.formView) this.formView = new api.views.form (model: api.todos). On ("gespeichert", Funktion ( ) api.router.navigate ("", trigger: true);) return this.formView;  

So ziemlich das selbe. Diesmal müssen wir jedoch etwas tun, sobald das Formular gesendet wurde. Und das leitet den Benutzer auf die Homepage weiter. Wie gesagt, jedes Objekt, das die Backbone.js-Klassen erweitert, ist eigentlich ein Event-Dispatcher. Es gibt Methoden wie auf und auslösen die du benutzen kannst.

Bevor wir mit dem Ansichtscode fortfahren, werfen wir einen Blick auf die HTML-Vorlage:

 

Wir haben ein Textbereich und ein Taste. Die Vorlage erwartet a Titel Parameter, der eine leere Zeichenfolge sein soll, wenn wir eine neue Aufgabe hinzufügen.

// views / form.js app.views.form = Backbone.View.extend (index: false, events: 'click button': 'save'), initialize: function () this.render (); , render: function (index) var template, html = $ ("# tpl-form"). html (); if (typeof index == 'undefined') this.index = false; template = _.template ( html, title: ""); else this.index = parseInt (index); this.todoForEditing = this.model.at (this.index); template = _.template ($ ("# tpl-form.) ") .html (), title: this.todoForEditing.get (" title ")); this. $ el.html (template); this. $ el.find (" textarea "). focus (); this.delegateEvents (); zurückgeben;, save: function (e) e.preventDefault (); var title = this. $ el.find ("textarea"). val (); if (title == "" ) alert ("Leeres Textfeld!"); return; if (this.index! == false) this.todoForEditing.set ("title", title); else this.model.add (title: title); this.trigger ("gespeichert");); 

Die Ansicht umfasst nur 40 Zeilen Code, macht aber seine Arbeit gut. Es ist nur ein Ereignis angehängt, und dies ist das Klicken auf die Schaltfläche "Speichern". Die Rendermethode verhält sich je nach übergeben unterschiedlich Index Parameter. Wenn wir beispielsweise eine ToDo bearbeiten, übergeben wir den Index und holen das genaue Modell ab. Wenn nicht, ist das Formular leer und eine neue Aufgabe wird erstellt. Der obige Code enthält mehrere interessante Punkte. Zuerst haben wir im Rendering die .Fokus() Methode, um den Fokus auf das Formular zu bringen, sobald die Ansicht gerendert wird. Wieder das DelegateEvents Funktion sollte aufgerufen werden, da das Formular getrennt und erneut angehängt werden konnte. Das sparen Methode beginnt mit e.preventDefault (). Dadurch wird das Standardverhalten der Schaltfläche entfernt, das in einigen Fällen möglicherweise das Formular sendet. Und am Ende haben wir, nachdem alles erledigt ist, die Gerettet Ereignis, das die Außenwelt darüber informiert, dass das ToDo in der Sammlung gespeichert ist.

Es gibt zwei Methoden für den Router, die wir ausfüllen müssen.

// App.js newToDo: function () var view = ViewsFactory.form (); api.title ("Create new ToDo:"). changeContent (view. $ el); view.render (), editToDo: Funktion (Index) var view = ViewsFactory.form (); api.title ("Edit:"). changeContent (view. $ el); view.render (index);  

Der Unterschied zwischen ihnen ist, dass wir einen Index übergeben, wenn der edit /: index Route ist abgestimmt. Und natürlich wird der Titel der Seite entsprechend geändert.

Einen Datensatz aus der Sammlung löschen

Für diese Funktion benötigen wir keine Ansicht. Die gesamte Arbeit kann direkt im Handler des Routers erledigt werden.

delteToDo: Funktion (Index) api.todos.remove (api.todos.at (parseInt (index))); api.router.navigate ("", trigger: true);  

Wir kennen den Index der ToDo, die wir löschen möchten. Da ist ein Löschen Methode in der Collection-Klasse, die ein Modellobjekt akzeptiert. Leiten Sie den Benutzer am Ende einfach zur Startseite weiter, auf der die aktualisierte Liste angezeigt wird.

Fazit

Backbone.js bietet alles, was Sie zum Erstellen einer voll funktionsfähigen Einzelseitenanwendung benötigen. Wir könnten es sogar an einen REST-Back-End-Service binden, und das Framework synchronisiert die Daten zwischen Ihrer App und der Datenbank. Der ereignisgesteuerte Ansatz ermöglicht eine modulare Programmierung sowie eine gute Architektur. Ich benutze Backbone.js persönlich für mehrere Projekte und es funktioniert sehr gut.