// Backbone.js 0.9.2
// (c) 2010–2012 Jeremy Ashkenas, DocumentCloud Inc.
// Backbone darf unter der MIT-Lizenz frei verbreitet werden.
// Für alle Details und Dokumentation:
// http://backbonejs.org
(Funktion() {
// Erstelle ein globales Objekt, dargestellt als Fensterobjekt im Browser und als globales Objekt in Node.js
var root = this;
// Den Wert der Variable „Backbone“ speichern, bevor er überschrieben wurde
// Wenn ein Namenskonflikt vorliegt oder die Spezifikation berücksichtigt wird, können Sie die Methode Backbone.noConflict() verwenden, um den Wert der Variablen wiederherzustellen, bevor sie von Backbone belegt wurde, und das Backbone-Objekt zum Umbenennen zurückzugeben
var previousBackbone = root.Backbone;
//Zwischenspeichern der Slice- und Splice-Methoden in Array.prototype in lokalen Variablen zum Aufrufen
var Slice = Array.prototype.slice;
var splice = Array.prototype.splice;
var Rückgrat;
if( Art der Exporte !== 'undefiniert') {
Rückgrat = Exporte;
} anders {
Backbone = root.Backbone = {};
}
//Backbone-Version definieren
Backbone.VERSION = '0.9.2';
// Underscore automatisch in die Serverumgebung importieren. Einige Methoden in Backbone hängen von Underscore ab oder erben von diesem.
var _ = root._;
if(!_ && ( typeof require !== 'undefiniert'))
_ = require('underscore');
// Definieren Sie die Bibliothek eines Drittanbieters als einheitliche Variable „$“, die zum Aufrufen von Methoden in der Bibliothek während der Ansicht (View), der Ereignisverarbeitung und der Synchronisierung mit Serverdaten (Sync) verwendet wird.
// Zu den unterstützten Bibliotheken gehören jQuery, Zepto usw. Sie haben die gleiche Syntax, aber Zepto eignet sich besser für die mobile Entwicklung. Es richtet sich hauptsächlich an Webkit-Kernbrowser.
// Sie können auch eine benutzerdefinierte Bibliothek mit einer jQuery-ähnlichen Syntax für die Verwendung durch Backbone anpassen (manchmal benötigen wir möglicherweise eine angepasste Version, die leichter als jQuery oder Zepto ist).
// Das hier definierte „$“ ist eine lokale Variable und hat daher keinen Einfluss auf die normale Verwendung von Bibliotheken von Drittanbietern außerhalb des Backbone-Frameworks.
var $ = root.jQuery ||. root.Zepto ||.
// Bibliotheken von Drittanbietern manuell einrichten
// Wenn Sie vor dem Import von Backbone keine Bibliothek eines Drittanbieters importiert haben, können Sie die lokale Variable „$“ über die Methode setDomLibrary festlegen
// Die setDomLibrary-Methode wird häufig auch zum dynamischen Importieren benutzerdefinierter Bibliotheken in Backbone verwendet.
Backbone.setDomLibrary = function(lib) {
$ = lib;
};
// Geben Sie die Benennung des Frameworks nach „Backbone“ auf und geben Sie das Backbone-Objekt zurück. Dies wird im Allgemeinen verwendet, um Namenskonflikte zu vermeiden oder Benennungsmethoden zu standardisieren
// Zum Beispiel:
// var bk = Backbone.noConflict(); // Brechen Sie die Benennung „Backbone“ ab und speichern Sie das Backbone-Objekt in der bk-Variablen
// console.log(Backbone); // Diese Variable kann nicht mehr auf das Backbone-Objekt zugreifen und wird auf den Wert vor der Definition von Backbone zurückgesetzt.
// var MyBackbone = bk; // Und bk speichert das Backbone-Objekt, wir benennen es in MyBackbone um
Backbone.noConflict = function() {
root.Backbone = previousBackbone;
gib dies zurück;
};
// Für Browser, die REST nicht unterstützen, können Sie Backbone.emulateHTTP = true setzen
// Die Serveranforderung wird im POST-Modus gesendet und der Parameter _method wird zu den Daten hinzugefügt, um den Operationsnamen zu identifizieren. Außerdem werden die Headerinformationen X-HTTP-Method-Override gesendet.
Backbone.emulateHTTP = false;
// Für Browser, die die Anwendungs-/JSON-Codierung nicht unterstützen, können Sie Backbone.emulateJSON = true;
// Setzen Sie den Anforderungstyp auf application/x-www-form-urlencoded und platzieren Sie die Daten im Modellparameter, um Kompatibilität zu erreichen
Backbone.emulateJSON = false;
// Backbone.Events im Zusammenhang mit benutzerdefinierten Ereignissen
// -------------------
// eventSplitter gibt die Parsing-Regeln für Ereignisnamen bei der Verarbeitung mehrerer Ereignisse an.
var eventSplitter = /s /;
// Benutzerdefinierter Event-Manager
// Durch die Bindung ereignisbezogener Methoden im Objekt ist es möglich, benutzerdefinierte Ereignisse zum Objekt hinzuzufügen, zu löschen und auszulösen.
var Events = Backbone.Events = {
// Benutzerdefinierte Ereignisse und Rückruffunktionen an das aktuelle Objekt binden
// Das Kontextobjekt in der Rückruffunktion ist der angegebene Kontext. Wenn der Kontext nicht festgelegt ist, wird als Kontextobjekt standardmäßig das Objekt des aktuell gebundenen Ereignisses verwendet.
// Diese Methode ähnelt der addEventListener-Methode in DOM Level2
// events ermöglicht die Angabe mehrerer Ereignisnamen, getrennt durch Leerzeichen (z. B. Leerzeichen, Tabulatoren usw.)
// Wenn der Ereignisname „all“ ist und ein Ereignis durch Aufrufen der Trigger-Methode ausgelöst wird, werden alle im „all“-Ereignis gebundenen Rückruffunktionen aufgerufen.
on: Funktion(Ereignisse, Rückruf, Kontext) {
//Definieren Sie lokale Variablen, die in einigen Funktionen verwendet werden
var-Aufrufe, Ereignis, Knoten, Schwanz, Liste;
//Die Callback-Funktion muss festgelegt werden
if(!callback)
gib dies zurück;
// Ereignisnamen über eventSplitter analysieren, mit Split mehrere Ereignisnamen in ein Array aufteilen
// Verwenden Sie im Allgemeinen Leerzeichen, um mehrere Ereignisnamen anzugeben
events = events.split(eventSplitter);
// Aufrufe zeichnen die Liste der im aktuellen Objekt gebundenen Ereignisse und Rückruffunktionen auf
ruft = this._callbacks ||. (this._callbacks = {});
// Durchlaufen Sie die Liste der Ereignisnamen und speichern Sie die Ereignisnamen vom Anfang bis zum Ende in der Ereignisvariablen.
while( event = events.shift()) {
// Holen Sie sich die Rückruffunktion, die an das Ereignisereignis gebunden wurde
// list speichert die Liste der Rückruffunktionen, die an einen einzelnen Ereignisnamen gebunden sind
// Die Funktionsliste wird nicht in einem Array gespeichert, sondern ist sequentiell über die nächsten Attribute mehrerer Objekte verknüpft.
/**数据格式如:
* {
* Schwanz: {Objekt},
* nächste: {
* Rückruf: {Funktion},
* Kontext: {Objekt},
* nächste: {
* Rückruf: {Funktion},
* Kontext: {Objekt},
* weiter: {Objekt}
* }
* }
* }*/
// Das nächste Objekt auf jeder Ebene der Liste speichert Informationen zu einem Rückrufereignis (Funktionskörper, Kontext und nächstes Rückrufereignis).
// Die oberste Ebene der Ereignisliste speichert ein Endobjekt, das die Kennung des letzten gebundenen Rückrufereignisses speichert (dasselbe Objekt wie das nächste des letzten Rückrufereignisses).
// Anhand der Endkennung können Sie beim Durchlaufen der Rückrufliste erkennen, dass die letzte Rückruffunktion erreicht wurde
list = Anrufe[Ereignis];
// Die Knotenvariable wird zum Aufzeichnen von Informationen zu dieser Rückruffunktion verwendet.
//tail speichert nur die Kennung der zuletzt gebundenen Callback-Funktion
// Wenn die Rückruffunktion zuvor gebunden wurde, weisen Sie daher den vorherigen Schwanz dem Knoten als Objekt zu und erstellen Sie dann einen neuen Objektbezeichner für den Schwanz
// Der Grund, warum dieses Rückrufereignis zum Endobjekt des vorherigen Rückrufs hinzugefügt wird, besteht darin, die Objekthierarchie der Rückruffunktionsliste in der Bindungsreihenfolge anzuordnen (das neueste gebundene Ereignis wird unten platziert).
node = list ? list.tail : {};
node.next = tail = {};
//Zeichnen Sie den Funktionskörper und die Kontextinformationen dieses Rückrufs auf
node.context = context;
node.callback = Rückruf;
// Die Rückrufliste des aktuellen Ereignisses neu zusammenstellen. Dieses Rückrufereignis wurde der Liste hinzugefügt
Aufrufe[Ereignis] = {
Schwanz: Schwanz,
next: Liste? list.next: Knoten
};
}
// Das aktuelle Objekt zurückgeben, um Methodenkettenaufrufe zu erleichtern
gib dies zurück;
},
// Gebundene Ereignisse oder Rückruffunktionen im Objekt entfernen Sie können die Ereignisse oder Rückruffunktionen, die gelöscht werden müssen, nach Ereignissen, Rückruf und Kontext filtern.
// – Wenn der Kontext leer ist, alle durch den Rückruf angegebenen Funktionen entfernen
// – Wenn der Rückruf leer ist, alle Rückruffunktionen im Ereignis entfernen
// – Wenn „events“ leer ist, aber Callback oder Kontext angegeben ist, entfernen Sie die durch Callback oder Kontext angegebene Callback-Funktion (Ereignisnamen werden nicht unterschieden).
// – Wenn keine Parameter übergeben werden, entfernen Sie alle im Objekt gebundenen Ereignisse und Rückruffunktionen
aus: Funktion(Ereignisse, Rückruf, Kontext) {
var-Ereignis, Aufrufe, Knoten, Schwanz, cb, ctx;
// Keine Ereignisse oder *alle* Ereignisse entfernen.
//An das aktuelle Objekt sind keine Ereignisse gebunden
if(!(calls = this._callbacks))
zurückkehren;
// Wenn keine Parameter angegeben sind, entfernen Sie alle Ereignisse und Rückruffunktionen (entfernen Sie das _callbacks-Attribut).
if(!(events || callback || context)) {
lösche dies._callbacks;
gib dies zurück;
}
// Analysieren Sie die Ereignisliste, die entfernt werden muss
// – Wenn Ereignisse angegeben sind, wird der Ereignisname gemäß eventSplitter analysiert
// – Wenn keine Ereignisse angegeben sind, analysieren Sie die Namensliste aller gebundenen Ereignisse
events = events ? events.split(eventSplitter) : _.keys(calls);
// Namensliste für Schleifenereignisse
while( event = events.shift()) {
// Das aktuelle Ereignisobjekt aus der Liste entfernen und in der Knotenvariablen zwischenspeichern
node = ruft[Ereignis] auf;
Anrufe löschen[Ereignis];
// Wenn das aktuelle Ereignisobjekt nicht vorhanden ist (oder keine Entfernungsfilterbedingungen angegeben sind, wird davon ausgegangen, dass das aktuelle Ereignis und alle Rückruffunktionen entfernt werden), beenden Sie diesen Vorgang (das Ereignisobjekt wurde im vorherigen Schritt entfernt). )
if(!node || !(callback || context))
weitermachen;
// Eine neue Liste erstellen und die angegebenen Rückrufe weglassen.
// Bauen Sie gemäß den Bedingungen der Rückruffunktion oder des Kontextfilters ein neues Ereignisobjekt zusammen und binden Sie es erneut
tail = node.tail;
// Alle Rückrufobjekte im Ereignis durchlaufen
while(( node = node.next) !== tail) {
cb = node.callback;
ctx = node.context;
// Basierend auf der Rückruffunktion und dem Kontext in den Parametern die Rückruffunktion filtern und die Rückruffunktion, die die Filterbedingungen nicht erfüllt, erneut an das Ereignis binden (da oben alle Rückruffunktionen im Ereignis entfernt wurden)
if((callback && cb !== callback) || (context && ctx !== context)) {
this.on(event, cb, ctx);
}
}
}
gib dies zurück;
},
// Ein oder mehrere definierte Ereignisse auslösen und die gebundene Rückruffunktionsliste nacheinander ausführen
Auslöser: Funktion(Ereignisse) {
var event, node,calls, tail, args, all, rest;
//An das aktuelle Objekt sind keine Ereignisse gebunden
if(!(calls = this._callbacks))
gib dies zurück;
// Die in der Callback-Funktionsliste gebundene Ereignisliste „all“ abrufen
all = ruft.all auf;
// Analysieren Sie den Ereignisnamen, der ausgelöst werden muss, gemäß den EventSplitter-Regeln in einem Array
events = events.split(eventSplitter);
// Zeichnen Sie die Parameter des Triggers von der zweiten bis zur restlichen Variablen auf, die wiederum an die Rückruffunktion übergeben werden.
rest = Slice.call(Argumente, 1);
// Durchlaufe die Liste der Ereignisse, die ausgelöst werden müssen
while( event = events.shift()) {
// Die Knotenvariable zeichnet hier eine Liste aller Callback-Funktionen des aktuellen Ereignisses auf
if( Knoten = Aufrufe[Ereignis]) {
//Die Tail-Variable zeichnet die Objekt-ID des letzten Bindungsereignisses auf
tail = node.tail;
//Der Wert der Knotenvariablen wird dem gebundenen einzelnen Callback-Ereignisobjekt der Reihe nach entsprechend der Bindungsreihenfolge des Ereignisses zugewiesen.
// Die nächste Eigenschaft des letzten gebundenen Ereignisses bezieht sich auf dasselbe Objekt wie tail und wird als Grundlage für die Beurteilung verwendet, ob das Ende der Liste erreicht wurde.
while(( node = node.next) !== tail) {
// Alle gebundenen Ereignisse ausführen und die Parameter beim Aufruf des Triggers an die Callback-Funktion übergeben
node.callback.apply(node.context || this, rest);
}
}
// Die Variable all zeichnet das „all“-Ereignis während der Bindung auf, d. h. wenn ein beliebiges Ereignis aufgerufen wird, wird die Rückruffunktion im „all“-Ereignis ausgeführt.
// – Die Rückruffunktionen im „all“-Ereignis werden unabhängig von der Bindungsreihenfolge nacheinander ausgeführt, nachdem alle Rückruffunktionslisten des aktuellen Ereignisses ausgeführt wurden.
// – Das „all“-Ereignis sollte automatisch aufgerufen werden, wenn ein normales Ereignis ausgelöst wird. Wenn das „all“-Ereignis ausgelöst werden muss, wird die Rückruffunktion im Ereignis zweimal ausgeführt.
if(Knoten = alle) {
tail = node.tail;
//Der Unterschied zum Aufruf der Rückruffunktion eines normalen Ereignisses besteht darin, dass das All-Ereignis den aktuell aufgerufenen Ereignisnamen als ersten Parameter an die Rückruffunktion übergibt.
args = [event].concat(rest);
// Durchlaufen und Ausführen der Callback-Funktionsliste im „all“-Ereignis
while(( node = node.next) !== tail) {
node.callback.apply(node.context || this, args);
}
}
}
gib dies zurück;
}
};
// Aliase für Bindungsereignisse und Release-Ereignisse, auch aus Kompatibilitätsgründen mit früheren Versionen von Backbone
Events.bind = Events.on;
Events.unbind = Events.off;
// Backbone.Model Datenobjektmodell
//-------------
// Model ist die Basisklasse aller Datenobjektmodelle in Backbone und wird zum Erstellen eines Datenmodells verwendet
// @param {Object}-Attribute geben die Initialisierungsdaten beim Erstellen des Modells an
// @param {Object}-Optionen
/*** @format-Optionen
* {
* analysieren: {Boolean},
* Sammlung: {Collection}
* }*/
var Model = Backbone.Model = function(attributes, options) {
// Die Standardvariable wird zum Speichern der Standarddaten des Modells verwendet
var-Standardwerte;
// Wenn der Attribute-Parameter nicht angegeben ist, setzen Sie Attribute auf ein leeres Objekt
Attribute ||. (Attribute = {});
//Legen Sie die Analysemethode für Attributstandarddaten fest. Die Standarddaten werden beispielsweise vom Server abgerufen (oder die Originaldaten liegen im XML-Format vor, um mit dem für die festgelegte Methode erforderlichen Datenformat kompatibel zu sein). -Methode kann zum Parsen verwendet werden.
if(Optionen && Optionen.parse)
attributes = this.parse(attributes);
if( defaults = getValue(this, 'defaults')) {
// Wenn das Modell bei der Definition Standarddaten festlegt, verwenden die Initialisierungsdaten die mit den Standardeinstellungen und Attributparametern zusammengeführten Daten (die Daten in den Attributen überschreiben die Daten mit demselben Namen in den Standardeinstellungen).
attributes = _.extend({}, defaults, attributes);
}
// Geben Sie explizit das Sammlungsobjekt an, zu dem das Modell gehört (beim Aufrufen der Add-, Push- und anderer Methoden der Sammlung, um das Modell zur Sammlung hinzuzufügen, wird das Sammlungsobjekt, zu dem das Modell gehört, automatisch festgelegt.)
if(Optionen && Optionen.Sammlung)
this.collection = options.collection;
//Das Attribut attributes speichert die JSON-objektivierten Daten des aktuellen Modells und ist beim Erstellen des Modells standardmäßig leer.
this.attributes = {};
// Definieren Sie das Cache-Objekt _escapedAttributes, das über die Escape-Methode verarbeitete Daten zwischenspeichert
this._escapedAttributes = {};
// Konfigurieren Sie für jedes Modell eine eindeutige Kennung
this.cid = _.uniqueId('c');
//Definieren Sie eine Reihe von Objekten, die zum Aufzeichnen des Datenstatus verwendet werden. Bitte beachten Sie die Kommentare beim Definieren des Objekts für spezifische Bedeutungen.
this.changed = {};
this._silent = {};
this._pending = {};
// Beim Erstellen einer Instanz Initialisierungsdaten festlegen. Wenn Sie den Silent-Parameter zum ersten Mal verwenden, wird das Änderungsereignis nicht ausgelöst.
this.set(Attribute, {
still: wahr
});
// Die Initialisierungsdaten wurden oben festgelegt. Der Status der geänderten, _silent- und _pending-Objekte hat sich möglicherweise hier geändert.
this.changed = {};
this._silent = {};
this._pending = {};
// Die Variable _ previousAttributes speichert eine Kopie der Modelldaten
// Wird verwendet, um den Status abzurufen, bevor die Modelldaten im Änderungsereignis geändert werden. Die Daten des vorherigen Status können über die Methode previous oder previousAttributes abgerufen werden.
this._ previousAttributes = _.clone(this.attributes);
//Initialisierungsmethode initialisieren aufrufen
this.initialize.apply(this, arguments);
};
// Verwenden Sie die Erweiterungsmethode, um eine Reihe von Eigenschaften und Methoden für den Modellprototyp zu definieren
_.extend(Model.prototype, Events, {
// Das geänderte Attribut zeichnet die Schlüsselsammlung der geänderten Daten jedes Mal auf, wenn die Set-Methode aufgerufen wird.
geändert: null,
// // Wenn das Silent-Attribut angegeben ist, wird das Änderungsereignis nicht ausgelöst und die geänderten Daten werden aufgezeichnet, bis das nächste Änderungsereignis ausgelöst wird.
// Das _silent-Attribut wird verwendet, um die geänderten Daten aufzuzeichnen, wenn Silent verwendet wird
_silent: null,
_pending: null,
// Das eindeutige Identifikationsattribut jedes Modells (Standard ist „id“, der Name des ID-Attributs kann durch Ändern von idAttribute angepasst werden)
// Wenn das ID-Attribut beim Festlegen der Daten enthalten ist, überschreibt die ID die ID des Modells.
// Die ID wird verwendet, um das Modell in der Sammlung zu finden und zu identifizieren. Bei der Kommunikation mit der Backend-Schnittstelle wird die ID auch als Kennung eines Datensatzes verwendet.
idAttribute: 'id',
// Modellinitialisierungsmethode, die automatisch aufgerufen wird, nachdem das Modell erstellt wurde
initialisieren: function() {
},
// Eine Kopie der Daten im aktuellen Modell zurückgeben (JSON-Objektformat)
toJSON: Funktion(Optionen) {
return _.clone(this.attributes);
},
// Rufen Sie den Datenwert im Modell anhand des attr-Attributnamens ab
get: function(attr) {
return this.attributes[attr];
},
// Entsprechend dem attr-Attributnamen den Datenwert im Modell abrufen. Die im Datenwert enthaltenen HTML-Sonderzeichen werden in HTML-Entitäten umgewandelt, einschließlich & <
// Implementiert durch die _.escape-Methode
Escape: Funktion(attr) {
varhtml;
// Daten aus dem _escapedAttributes-Cache-Objekt suchen und direkt zurückgeben, wenn die Daten zwischengespeichert wurden
if(html = this._escapedAttributes[attr])
html zurückgeben;
// Keine Daten im _escapedAttributes-Cache-Objekt gefunden
// Dann zuerst die Daten aus dem Modell abrufen
var val = this.get(attr);
// Konvertieren Sie den HTML-Code in den Daten mithilfe der _.escape-Methode in Entitäten und speichern Sie ihn im _escapedAttributes-Objekt, um ihn beim nächsten Mal leicht abrufen zu können
return this._escapedAttributes[attr] = _.escape(val == null ? '' : '' val);
},
// Überprüfen Sie, ob ein bestimmtes Attribut im Modell vorhanden ist. Wenn der Wert des Attributs in einen booleschen Typ konvertiert wird und der Wert falsch ist, wird davon ausgegangen, dass er nicht vorhanden ist.
// Wenn der Wert false, null, undefiniert, 0, NaN oder eine leere Zeichenfolge ist, wird er in false konvertiert
hat: function(attr) {
return this.get(attr) != null;
},
//Legen Sie die Daten im Modell fest. Wenn der Schlüsselwert nicht vorhanden ist, wird er als neues Attribut zum Modell hinzugefügt. Wenn der Schlüsselwert bereits vorhanden ist, wird er auf den neuen Wert geändert.
set: Funktion(Schlüssel, Wert, Optionen) {
// Notieren Sie die Datenobjekte, die in der Variablen attrs festgelegt werden müssen
var attrs, attr, val;
// Die Parameterform ermöglicht die Form von Schlüssel-Wert-Objekten oder separate Einstellungen über Schlüssel- und Wertparameter.
// Wenn der Schlüssel ein Objekt ist, gilt er als in Objektform festgelegt und der zweite Parameter wird als Optionsparameter betrachtet.
if(_.isObject(key) || key == null) {
attrs = Schlüssel;
Optionen = Wert;
} anders {
// Legen Sie die beiden Parameter Schlüssel und Wert getrennt fest und fügen Sie die Daten zur einheitlichen Verarbeitung in das Attrs-Objekt ein.
attrs = {};
attrs[key] = value;
}
// Das Optionskonfigurationselement muss ein Objekt sein. Wenn Optionen nicht festgelegt sind, ist der Standardwert ein leeres Objekt.
Optionen ||. ( Optionen = {});
// Es wird keine Aktion ausgeführt, wenn keine Parameter festgelegt sind.
if(!attrs)
gib dies zurück;
// Wenn das festzulegende Datenobjekt zu einer Instanz der Model-Klasse gehört, weisen Sie attrs das Attributdatenobjekt des Model-Objekts zu
// Im Allgemeinen wird diese Aktion ausgeführt, wenn Daten von einem Modellobjekt in ein anderes Modellobjekt kopiert werden.
if(attrs-Instanz des Modells)
attrs = attrs.attributes;
// Wenn das unset-Attribut im Optionskonfigurationsobjekt festgelegt ist, setzen Sie alle Attribute im attrs-Datenobjekt auf undefiniert zurück
// Im Allgemeinen wird dieser Vorgang ausgeführt, wenn Daten von einem Modellobjekt in ein anderes Modellobjekt kopiert werden. Es müssen jedoch nur die Daten im Modell kopiert werden, ohne dass der Wert kopiert wird.
if(options.unset)
for(attr in attrs)
attrs[attr] =
ungültig 0;
//Überprüfen Sie die aktuellen Daten und stoppen Sie die Ausführung, wenn die Überprüfung fehlschlägt
if(!this._validate(attrs, options))
return false;
// Wenn der festgelegte ID-Attributname in der Datensammlung enthalten ist, überschreiben Sie die ID mit dem ID-Attribut des Modells
// Dies soll sicherstellen, dass nach dem Anpassen des ID-Attributnamens beim Zugriff auf das ID-Attribut des Modells korrekt auf die ID zugegriffen werden kann.
if(this.idAttribute in attrs)
this.id = attrs[this.idAttribute];
var changes = options.changes = {};
// zeichnet jetzt die Datenobjekte im aktuellen Modell auf
var now = this.attributes;
// escaped zeichnet die durch Escape im aktuellen Modell zwischengespeicherten Daten auf
var escaped = this._escapedAttributes;
// prev zeichnet den Wert auf, bevor die Daten im Modell geändert werden
var prev = this._ previousAttributes || {};
// Durchlaufen Sie die Datenobjekte, die festgelegt werden müssen
for(attr in attrs) {
// attr speichert den aktuellen Attributnamen, val speichert den aktuellen Attributwert
val = attrs[attr];
// Wenn die aktuellen Daten nicht im Modell vorhanden sind oder sich geändert haben oder das Löschen nicht gesetzter Attribute in den Optionen angegeben ist, löschen Sie die Daten, die durch die Daten in _escapedAttributes ersetzt wurden.
if(!_.isEqual(now[attr], val) || (options.unset && _.has(now, attr))) {
// Nur durch Escape zwischengespeicherte Daten löschen. Dadurch wird sichergestellt, dass die Daten im Cache mit den tatsächlichen Daten im Modell synchronisiert werden.
delete escaped[attr];
// Wenn das Silent-Attribut angegeben ist, wird das Änderungsereignis durch diesen Aufruf der Set-Methode nicht ausgelöst, sodass die geänderten Daten im _silent-Attribut aufgezeichnet werden, sodass beim nächsten Auslösen des Änderungsereignisses die Ereignisüberwachungsfunktion ausgeführt wird benachrichtigt, dass sich die Daten geändert haben.
// Wenn das Silent-Attribut nicht angegeben ist, setzen Sie die aktuellen Daten im Changes-Attribut direkt auf den geänderten Status.
(options.silent ? this._silent : changes)[attr] = true;
}
// Wenn in den Optionen „unset“ festgelegt ist, löschen Sie die Daten (einschließlich Schlüssel) aus dem Modell
// Wenn das nicht gesetzte Attribut nicht angegeben ist, wird davon ausgegangen, dass neue oder geänderte Daten hinzugefügt werden und dem Datenobjekt des Modells neue Daten hinzugefügt werden.
Optionen.unset?
now[attr] löschen: now[attr] = val;
// Wenn die Daten im Modell nicht mit den neuen Daten übereinstimmen, bedeutet dies, dass sich die Daten geändert haben
if(!_.isEqual(prev[attr], val) || (_.has(now, attr) != _.has(prev, attr))) {
// Den geänderten Status des aktuellen Attributs im geänderten Attribut aufzeichnen
this.changed[attr] = val;
if(!options.silent)
this._pending[attr] = true;
} anders {
// Wenn sich die Daten nicht geändert haben, entfernen Sie den geänderten Status aus dem geänderten Attribut
delete this.changed[attr];
lösche dies._pending[attr];
}
}
// Rufen Sie die Änderungsmethode auf, die die an das Änderungsereignis gebundene Funktion auslöst
if(!options.silent)
this.change(options);
gib dies zurück;
},
//Löschen Sie die angegebenen Daten aus dem aktuellen Modell (Attribute werden gleichzeitig auch gelöscht)
unset: function(attr, options) {
(Optionen || ( Optionen = {})).unset = true;
// Informieren Sie die Set-Methode über das Konfigurationselement „options.unset“ über die Ausführung des Löschvorgangs
return this.set(attr, null, options);
},
// Alle Daten und Attribute im aktuellen Modell löschen
klar: Funktion(Optionen) {
(Optionen || ( Optionen = {})).unset = true;
// Klonen Sie eine Kopie der Eigenschaften des aktuellen Modells und weisen Sie die Set-Methode an, den Löschvorgang über das Konfigurationselement options.unset durchzuführen
return this.set(_.clone(this.attributes), options);
},
// Erhalten Sie die Standardmodelldaten vom Server. Verwenden Sie nach dem Abrufen der Daten die Set-Methode, um die Daten in das Modell einzufügen. Wenn die erhaltenen Daten nicht mit den Daten im aktuellen Modell übereinstimmen, wird das Änderungsereignis ausgelöst .
fetch: Funktion(Optionen) {
// Stellen Sie sicher, dass „Optionen“ ein neues Objekt ist, und ändern Sie dann die Eigenschaften in „Optionen“.
Optionen = Optionen ? _.clone(Optionen): {};
var model = this;
// In Optionen können Sie eine benutzerdefinierte Rückruffunktion angeben, nachdem die Daten erfolgreich abgerufen wurden.
var success = options.success;
// Wenn die Daten erfolgreich abgerufen wurden, geben Sie die Daten ein und rufen Sie die benutzerdefinierte Erfolgsrückruffunktion auf
options.success = function(resp, status, xhr) {
// Konvertieren Sie die vom Server über die Parse-Methode zurückgegebenen Daten
// Füllen Sie die konvertierten Daten über die Set-Methode in das Modell ein, damit das Änderungsereignis ausgelöst werden kann (wenn sich die Daten ändern).
// Wenn die Validierung beim Ausfüllen der Daten fehlschlägt, wird die benutzerdefinierte Erfolgsrückruffunktion nicht aufgerufen
if(!model.set(model.parse(resp, xhr), Optionen))
return false;
//Rufen Sie die benutzerdefinierte Erfolgsrückruffunktion auf
wenn(Erfolg)
Erfolg(Modell bzw.);
};
// Behandeln Sie das Fehlerereignis über wrapError, wenn in der Anfrage ein Fehler auftritt
options.error = Backbone.wrapError(options.error, model, options);
// Rufen Sie die Sync-Methode auf, um Daten vom Server abzurufen
return (this.sync || Backbone.sync).call(this, 'read', this, options);
},
//Speichern Sie die Daten im Modell auf dem Server
Speichern: Funktion(Schlüssel, Wert, Optionen) {
// attrs speichert die Datenobjekte, die auf dem Server gespeichert werden müssen
var attrs, aktuell;
//Unterstützt das Festlegen eines einzelnen Attributschlüssels: Wert
// Batch-Einstellungsmethode in Objektform unterstützen {key: value}
if(_.isObject(key) || key == null) {
// Wenn der Schlüssel ein Objekt ist, wird davon ausgegangen, dass er über die Objektmethode festgelegt wird
// Zu diesem Zeitpunkt gilt der zweite Parameter als Optionen
attrs = Schlüssel;
Optionen = Wert;
}anders {
// Wenn ein einzelnes Attribut in Form von key: value festgelegt ist, legen Sie attrs direkt fest
attrs = {};
attrs[key] = value;
}
// Das Konfigurationsobjekt muss ein neues Objekt sein
Optionen = Optionen ? _.clone(Optionen): {};
// Wenn die Warteoption in den Optionen festgelegt ist, werden die geänderten Daten im Voraus überprüft. Wenn der Server nicht auf die neuen Daten antwortet (oder die Antwort fehlschlägt), werden die lokalen Daten in den Zustand vor der Änderung zurückversetzt.
// Wenn die Warteoption nicht festgelegt ist, werden die lokalen Daten unabhängig davon, ob der Server erfolgreich eingestellt wurde, auf den neuesten Stand geändert.
if(options.wait) {
// Überprüfen Sie im Voraus, welche Daten gespeichert werden müssen
if(!this._validate(attrs, options))
return false;
// Daten im aktuellen Modell aufzeichnen und zum Wiederherstellen der Daten nach dem Senden an den Server verwenden
// Wenn die Serverantwort fehlschlägt oder keine Daten zurückgegeben werden, kann der Zustand vor der Änderung beibehalten werden
current = _.clone(this.attributes);
}
// SilentOptions fügt Silent zum Optionsobjekt hinzu (keine Datenüberprüfung)
// Verwenden Sie das Konfigurationselement „silentOptions“, wenn Sie den Parameter „wait“ verwenden, da die Daten oben überprüft wurden
// Wenn der Warteparameter nicht gesetzt ist, werden die ursprünglichen Optionskonfigurationselemente weiterhin verwendet
var SilentOptions = _.extend({}, Optionen, {
still: wahr
});
// Speichern Sie die zuletzt geänderten Daten im Modell, damit die Modelldaten mit der Synchronisierungsmethode abgerufen und auf dem Server gespeichert werden können.
if(attrs && !this.set(attrs, options.wait ? SilentOptions : Optionen)) {
return false;
}
var model = this;
// In den Optionen können Sie nach erfolgreichem Speichern der Daten eine benutzerdefinierte Rückruffunktion angeben.
var success = options.success;
// Erfolgreich ausführen, nachdem der Server erfolgreich geantwortet hat
options.success = function(resp, status, xhr) {
// Die neuesten Statusdaten der Antwort des Servers abrufen
var serverAttrs = model.parse(resp, xhr);
// Wenn der Warteparameter verwendet wird, wird der geänderte Datenstatus zuerst direkt auf das Modell gesetzt.
if(options.wait) {
Optionen löschen.wait;
serverAttrs = _.extend(attrs || {}, serverAttrs);
}
//Setzen Sie den neuesten Datenstatus in das Modell ein
// Wenn die Überprüfung beim Aufrufen der Set-Methode fehlschlägt, wird die benutzerdefinierte Erfolgsrückruffunktion nicht aufgerufen.
if(!model.set(serverAttrs, Optionen))
return false;
if(success) {
// Rufen Sie die benutzerdefinierte Erfolgsrückruffunktion auf, nachdem die Antwort erfolgreich war
Erfolg(Modell bzw.);
} anders {
// Wenn kein benutzerdefinierter Rückruf angegeben ist, wird das Synchronisierungsereignis standardmäßig ausgelöst
model.trigger('sync', model, resp, options);
}
};
// Behandeln Sie das Fehlerereignis über wrapError, wenn in der Anfrage ein Fehler auftritt
options.error = Backbone.wrapError(options.error, model, options);
//Speichern Sie die Daten im Modell auf dem Server
// Wenn das aktuelle Modell ein neu erstelltes Modell (ohne ID) ist, verwenden Sie die Erstellungsmethode (neu), andernfalls wird es als Aktualisierungsmethode (geändert) betrachtet.
var method = this.isNew() ? 'create' : 'update';
var xhr = (this.sync || Backbone.sync).call(this, method, this, options);
// Wenn options.wait festgelegt ist, stellen Sie die Daten in den Zustand vor der Änderung wieder her
// Die gespeicherte Anfrage hat zu diesem Zeitpunkt keine Antwort erhalten. Wenn die Antwort fehlschlägt, bleibt das Modell im Zustand vor der Änderung. Wenn der Server erfolgreich antwortet, werden die Daten im Modell auf den neuesten Erfolgsstatus gesetzt .
if(options.wait)
this.set(current, SilentOptions);
return xhr;
},
// Modell löschen. Das Modell wird aus der Sammlung gelöscht, zu der es gehört.
// Wenn das Modell auf dem Client erstellt wird, löschen Sie es direkt vom Client.
// Wenn die Modelldaten gleichzeitig auf dem Server vorhanden sind, werden gleichzeitig die serverseitigen Daten gelöscht.
zerstören: Funktion(Optionen) {
// Das Konfigurationselement muss ein neues Objekt sein
Optionen = Optionen ? _.clone(Optionen): {};
var model = this;
// In den Optionen können Sie eine benutzerdefinierte Rückruffunktion angeben, nachdem die Daten erfolgreich gelöscht wurden.
var success = options.success;
// Erfolgreich aufgerufen, um Daten zu löschen, wird das Zerstörungsereignis ausgelöst. Wenn das Modell in der Sammlung vorhanden ist, hört die Sammlung auf das Zerstörungsereignis und entfernt das Modell aus der Sammlung, wenn es ausgelöst wird.
// Beim Löschen eines Modells werden die Daten im Modell nicht gelöscht, aber das Modell wurde aus der Sammlung entfernt. Wenn also nirgendwo ein Verweis auf das Modell vorhanden ist, wird es automatisch aus dem Speicher freigegeben.
// Es wird empfohlen, beim Löschen des Modells die Referenzvariable des Modellobjekts auf Null zu setzen.
var triggerDestroy = function() {
model.trigger('destroy', model, model.collection, options);
};
// Wenn es sich bei dem Modell um ein vom Client neu erstelltes Modell handelt, rufen Sie triggerDestroy direkt auf, um das Modell aus der Sammlung zu entfernen.
if(this.isNew()) {
triggerDestroy();
return false;
}// Wenn das Löschen von Daten vom Server erfolgreich ist
options.success = function(bzw.) {
// Wenn das Warteelement im Optionsobjekt konfiguriert ist, bedeutet dies, dass die Modelldaten im lokalen Speicher gelöscht werden, nachdem die Serverdaten erfolgreich gelöscht wurden.
// Wenn die Serverantwort fehlschlägt, werden die lokalen Daten nicht gelöscht
if(options.wait)
triggerDestroy();
if(success) {
//Rufen Sie die benutzerdefinierte Erfolgsrückruffunktion auf
Erfolg(Modell bzw.);
} anders {
// Wenn kein benutzerdefinierter Rückruf vorhanden ist, wird das Synchronisierungsereignis standardmäßig ausgelöst
model.trigger('sync', model, resp, options);
}
};
// Behandeln Sie das Fehlerereignis über wrapError, wenn in der Anfrage ein Fehler auftritt
options.error = Backbone.wrapError(options.error, model, options);
//Senden Sie eine Anfrage zum Löschen von Daten über die Synchronisierungsmethode
var xhr = (this.sync || Backbone.sync).call(this, 'delete', this, options);
// Wenn das Warteelement im Optionsobjekt nicht konfiguriert ist, werden zuerst die lokalen Daten gelöscht und dann wird eine Anfrage zum Löschen der Serverdaten gesendet.
// Zu diesem Zeitpunkt wurden die lokalen Modelldaten gelöscht, unabhängig davon, ob die Serverlöschung erfolgreich war oder nicht.
if(!options.wait)
triggerDestroy();
return xhr;
},
// Rufen Sie die dem Modell entsprechende URL in der Serverschnittstelle ab. Beim Aufrufen von Save-, Fetch-, Destroy- und anderen Methoden zur Interaktion mit dem Server wird diese Methode zum Abrufen der URL verwendet.
// Die generierte URL ähnelt dem „PATHINFO“-Modus. Der Server verfügt nur über eine URL für Modellvorgänge. Bei Änderungs- und Löschvorgängen wird die Modell-ID zur einfachen Identifizierung angehängt.
// Wenn urlRoot im Modell definiert ist, sollte die Serverschnittstelle die Form [urlRoot/id] haben.
// Wenn die Sammlung, zu der das Modell gehört, die URL-Methode oder das URL-Attribut definiert, verwenden Sie das URL-Formular in der Sammlung: [collection.url/id]
// Beim Zugriff auf die Server-URL wird die Modell-ID an die URL angehängt, um dem Server die Identifizierung eines Datensatzes zu erleichtern. Daher muss die ID im Modell mit dem Serverdatensatz übereinstimmen.
// Wenn die URL des Modells oder der Sammlung nicht abgerufen werden kann, wird die Methode urlError aufgerufen und eine Ausnahme ausgelöst.
// Wenn die Serverschnittstelle nicht nach „PATHINFO“ organisiert ist, können Sie durch Überlastung der URL-Methode eine nahtlose Interaktion mit dem Server erreichen.
URL: Funktion() {
//Definieren Sie den URL-Pfad, der dem Server entspricht
var base = getValue(this, 'urlRoot') ||. getValue(this.collection, 'url') ||.
// Wenn das aktuelle Modell ein vom Client neu erstelltes Modell ist, gibt es kein ID-Attribut und die Server-URL verwendet direkt base.
if(this.isNew())
Rückkehrbasis;
// Wenn das aktuelle Modell ein ID-Attribut hat, kann die Save- oder Destroy-Methode aufgerufen werden und die ID des Modells wird an die Basis angehängt.
// Im Folgenden wird ermittelt, ob das letzte Zeichen der Basis „/“ ist und das generierte URL-Format [base/id] ist.
return base (base.charAt(base.length - 1) == '/' ? '' : '/') encodeURIComponent(this.id);
},
// Die Parse-Methode wird verwendet, um die vom Server erhaltenen Daten zu analysieren und Modelldaten zurückzugeben, die von der Set-Methode analysiert werden können.
// Im Allgemeinen wird die Parse-Methode basierend auf den vom Server zurückgegebenen Daten überlastet, um eine nahtlose Verbindung mit dem Server aufzubauen.
// Wenn die vom Server zurückgegebene Datenstruktur nicht mit der für die Set-Methode erforderlichen Datenstruktur übereinstimmt (z. B. wenn der Server Daten im XML-Format zurückgibt), kann die Parse-Methode zur Konvertierung verwendet werden.
analysieren: function(resp, xhr) {
zurück bzw. zurück;
},
// Erstellen Sie ein neues Modell mit denselben Daten wie das aktuelle Modell
Klon: function() {
return new this.constructor(this.attributes);
},
// Überprüfen Sie, ob das aktuelle Modell ein neues, vom Client erstelltes Modell ist
// Die Prüfmethode basiert darauf, ob das Modell eine ID-ID hat. Das vom Client erstellte neue Modell hat keine ID-ID.
// Daher müssen die vom Server geantworteten Modelldaten den ID-Bezeichner enthalten. Der Attributname des Bezeichners lautet standardmäßig „id“. Sie können den Bezeichner auch anpassen, indem Sie das idAttribute-Attribut ändern.
isNew : function() {
return this.id == null;
},
// Funktion, die die Änderungsereignisbindung auslöst, wenn Daten aktualisiert werden
// Wenn die Set-Methode aufgerufen wird, wird die Change-Methode automatisch aufgerufen. Wenn beim Aufruf der Set-Methode die stille Konfiguration angegeben wird, muss die Change-Methode manuell aufgerufen werden.
ändern: Funktion(Optionen) {
// Optionen müssen ein Objekt sein
Optionen ||. ( Optionen = {});
// Es gibt einige Probleme mit der Logik im Zusammenhang mit this._changing
// this._changing wird am Ende der Methode auf false gesetzt, sodass der Wert der sich ändernden Variablen über der Methode immer false ist (das erste Mal ist undefiniert)
// Die ursprüngliche Absicht des Autors sollte darin bestehen, diese Variable zu verwenden, um anzuzeigen, ob die Änderungsmethode ausgeführt wurde. Sie ist für Single-Thread-Skripte auf der Browserseite bedeutungslos, da diese Methode bei der Ausführung andere Skripte blockiert.
// Ändern erhält den Status der letzten Ausführung. Wenn das letzte Skript nicht ausgeführt wurde, ist der Wert wahr.
var Changing = this._changing;
//Ausführung des Flags starten. Der Wert ist während der Ausführung immer true. Nach der Ausführung wird this._changing in false geändert.
this._changing = true;
//Füge einen anderen Datenstatus als diese Änderung zum _pending-Objekt hinzu
for(var attr in this._silent)
this._pending[attr] = true;
// Das Changes-Objekt enthält alle Daten, die seit der letzten Ausführung des Änderungsereignisses für die aktuellen Daten geändert wurden.
// Wenn das Änderungsereignis zuvor nicht durch die Verwendung von Silent ausgelöst wurde, wird es dieses Mal im Änderungsobjekt platziert.
var changes = _.extend({}, options.changes, this._silent);
//_silent-Objekt zurücksetzen
this._silent = {};
// Durchlaufen Sie das Änderungsobjekt und lösen Sie separate Änderungsereignisse für jedes Attribut aus.
for(var attr in changes) {
// Übergeben Sie das Modellobjekt, die Attributwerte und die Konfigurationselemente als Parameter an die Ereignisüberwachungsfunktion
this.trigger('change:' attr, this, this.get(attr), Optionen);
}
//Wenn die Methode ausgeführt wird, stoppen Sie die Ausführung
wenn(sich ändern)
gib dies zurück;
// Das Änderungsereignis auslösen. Nachdem Daten geändert wurden, werden nacheinander das Ereignis „change:property“ und das Ereignis „change“ ausgelöst.
while(!_.isEmpty(this._pending)) {
this._pending = {};
// Das Änderungsereignis auslösen und die Modellinstanz und Konfigurationselemente als Parameter an die Überwachungsfunktion übergeben
this.trigger('change', this, options);
// Durchlaufen Sie die Daten im geänderten Objekt und entfernen Sie den Status der geänderten Daten wiederum aus geändert
// Wenn Sie danach hasChanged aufrufen, um den Datenstatus zu überprüfen, erhalten Sie false (unverändert)
for(var attr in this.changed) {
if(this._pending[attr] || this._silent[attr])
weitermachen;
//Entferne den Status der geänderten Daten
delete this.changed[attr];
}
// Nachdem das Änderungsereignis ausgeführt wurde, zeichnet das _ previousAttributes-Attribut die neueste Datenkopie des aktuellen Modells auf
// Wenn Sie daher den vorherigen Status der Daten abrufen müssen, können Sie ihn normalerweise nur über die Methode previous oder previousAttributes im ausgelösten Änderungsereignis abrufen.
this._ previousAttributes = _.clone(this.attributes);
}
//Flag „Ausführung abgeschlossen“.
this._changing = false;
gib dies zurück;
},
// Prüfen, ob bestimmte Daten seit der Ausführung des letzten Änderungsereignisses geändert wurden
/*** Wird im Allgemeinen in Verbindung mit der Methode previous oder previousAttributes im Änderungsereignis verwendet, z. B.:
* if(model.hasChanged('attr')) {
* var attrPrev = model. previous('attr');
* }*/
hasChanged: function(attr) {
if(!arguments.length)
return !_.isEmpty(this.changed);
return _.has(this.changed, attr);
},
// Holen Sie sich die Datensammlung im aktuellen Modell und die Daten, die sich in den letzten Daten geändert haben
// (Im Allgemeinen wird die Änderungsmethode nicht aufgerufen, wenn das stille Attribut verwendet wird, sodass die Daten vorübergehend im geänderten Attribut gespeichert werden. Die letzten Daten können über die previousAttributes-Methode abgerufen werden.)
// Wenn ein Diff-Set übergeben wird, werden die letzten Modelldaten mit den Daten im Diff-Set verglichen und ein inkonsistenter Datensatz zurückgegeben.
// Wenn es keinen Unterschied im Vergleichsergebnis gibt, gebe false zurück
geänderteAttribute: function(diff) {
// Wenn diff nicht angegeben ist, wird die Datensammlung des aktuellen Modells zurückgegeben, die sich gegenüber dem vorherigen Zustand geändert hat. Diese Daten wurden im geänderten Attribut gespeichert, sodass eine Kopie der geänderten Sammlung zurückgegeben wird.
if(!diff)
return this.hasChanged() ? _.clone(this.changed) : false;
// Der zu vergleichende Diff-Satz wird angegeben und das Vergleichsergebnis zwischen den letzten Daten und dem Diff-Satz wird zurückgegeben.
//Die alte Variable speichert die Modelldaten des vorherigen Zustands
var val, changes = false, old = this._ previousAttributes;
// Durchlaufe die Diff-Sammlung und vergleiche jedes Element mit der Sammlung vorheriger Zustände
for(var attr in diff) {
// Daten mit inkonsistenten Vergleichsergebnissen vorübergehend in der geänderten Variablen speichern
if(_.isEqual(old[attr], ( val = diff[attr])))
weitermachen;
(geändert || (geändert = {}))[attr] = val;
}
// Das Vergleichsergebnis zurückgeben
Rückgabe geändert;
},
// Erhalten Sie in dem vom Modell ausgelösten Änderungsereignis die Daten des vorherigen Zustands vor der Änderung eines Attributs, die im Allgemeinen für Datenvergleiche oder Rollbacks verwendet werden.
// Diese Methode wird im Allgemeinen im Änderungsereignis aufgerufen. Nachdem das Änderungsereignis ausgelöst wurde, speichert das _ previousAttributes-Attribut die neuesten Daten.
vorherige: function(attr) {
// attr gibt den Attributnamen an, der den vorherigen Status abrufen muss
if(!arguments.length || !this._ previousAttributes)
null zurückgeben;
return this._ previousAttributes[attr];
},
// Wenn das Modell das Änderungsereignis auslöst, erhalten Sie die Datensammlung des vorherigen Status aller Attribute
// Diese Methode ähnelt der previous()-Methode. Sie wird im Allgemeinen im Änderungsereignis aufgerufen und für den Datenvergleich oder das Rollback verwendet.
previousAttributes : function() {
// Klonen Sie das Datenobjekt des vorherigen Status in ein neues Objekt und kehren Sie zurück
return _.clone(this._ previousAttributes);
},
// Überprüfen Sie, ob sich das Modell derzeit in einem gültigen Zustand befindet. Dies ist nur möglich
// in einen *ungültigen* Zustand geraten, wenn Sie stille Änderungen verwenden.
// Überprüfen Sie, ob die Daten im aktuellen Modell mit der Validierungsmethode überprüft werden können. Stellen Sie vor dem Aufruf sicher, dass die Validierungsmethode definiert ist.
isValid: function() {
return !this.validate(this.attributes);
},
// Die Datenüberprüfungsmethode wird automatisch ausgeführt, wenn Set-, Save-, Add- und andere Datenaktualisierungsmethoden aufgerufen werden.
// Ein Fehler bei der Überprüfung löst das Ereignis „error“ des Modellobjekts aus. Wenn in den Optionen eine Fehlerverarbeitungsfunktion angegeben ist, wird nur die Funktion „options.error“ ausgeführt.
// @param {Object} attrs Attribute des Datenmodells, das die objektivierten Daten des Modells speichert
// @param {Object} Optionenkonfigurationselemente
// @return {Boolean} Gibt „true“ zurück, wenn die Überprüfung erfolgreich ist, und „false“, wenn sie fehlschlägt.
_validate: function(attrs, options) {
// Wenn das Attribut „options.silent“ beim Aufrufen von Set-, Save-, Add- und anderen Datenaktualisierungsmethoden festgelegt ist, wird die Überprüfung ignoriert
// Wenn die Validierungsmethode nicht zum Modell hinzugefügt wird, wird die Validierung ignoriert
if(options.silent || !this.validate)
return true;
// Alle Attributwerte im Objekt abrufen und zur Überprüfung in die Validierungsmethode einfügen
// Die Validierungsmethode enthält zwei Parameter, nämlich das Datenerfassungs- und Konfigurationsobjekt im Modell. Wenn die Validierung erfolgreich ist, werden keine Daten zurückgegeben (der Standardwert ist undefiniert). Wenn die Validierung fehlschlägt, werden Daten mit Fehlerinformationen zurückgegeben .
attrs = _.extend({}, this.attributes, attrs);
var error = this.validate(attrs, options);
//Verifizierung bestanden
if(!error)
return true;
// Überprüfung fehlgeschlagen
// Wenn die Fehlerbehandlungsmethode im Konfigurationsobjekt festgelegt ist, rufen Sie diese Methode auf und übergeben Sie die Fehlerdaten und das Konfigurationsobjekt an diese Methode
if(Optionen && Optionen.error) {
options.error(this, error, options);
} anders {
// Wenn ein Fehlerereignis-Listener an das Modell gebunden ist, wird das Bindungsereignis ausgelöst.
this.trigger('error', this, error, options);
}
//Identifizierung der Rückgabebestätigung fehlgeschlagen
return false;
}
});
// Backbone.Collection Datenmodellsammlung bezogen
//------------------
// Collection speichert eine Reihe von Datenmodellen derselben Klasse und stellt zugehörige Methoden zum Betreiben der Modelle bereit
var Collection = Backbone.Collection = function(models, options) {
//Konfigurationsobjekt
Optionen ||. ( Optionen = {});
//Legen Sie die Modellklasse der Sammlung in den Konfigurationsparametern fest
if(options.model)
this.model = options.model;
// Wenn das Komparatorattribut festgelegt ist, werden die Daten in der Sammlung gemäß dem Sortieralgorithmus in der Komparatormethode sortiert (dieser wird automatisch in der Add-Methode aufgerufen).
if(options.comparator)
this.comparator = options.comparator;
// Den internen Status der Sammlung bei der Instanziierung zurücksetzen (der erste Aufruf kann als Definitionsstatus verstanden werden)
this._reset();
// Rufen Sie die benutzerdefinierte Initialisierungsmethode auf. Bei Bedarf wird die Initialisierungsmethode im Allgemeinen überladen.
this.initialize.apply(this, arguments);
// Wenn Modelldaten angegeben sind, rufen Sie die Reset-Methode auf, um die Daten zur Sammlung hinzuzufügen.
// Der Silent-Parameter wird beim ersten Aufruf gesetzt, sodass das „reset“-Ereignis nicht ausgelöst wird.
if(Modelle)
this.reset(Modelle, {
still: wahr,
analysieren: Optionen.parse
});
};
// Definieren Sie die Prototypmethode der Sammlungsklasse über die Erweiterungsmethode
_.extend(Collection.prototype, Events, {
// Definieren Sie die Modellklasse der Sammlung. Die Modellklasse muss eine Unterklasse von Backbone.Model sein
// Bei Verwendung sammlungsbezogener Methoden (z. B. Hinzufügen, Erstellen usw.) dürfen Datenobjekte übergeben werden. Die Sammlungsmethode erstellt automatisch die entsprechende Instanz gemäß der definierten Modellklasse.
//Die in der Sammlung gespeicherten Datenmodelle sollten alle Instanzen derselben Modellklasse sein
Modell: Modell,
// Initialisierungsmethode, diese Methode wird automatisch aufgerufen, nachdem die Sammlungsinstanz erstellt wurde
// Diese Methode wird im Allgemeinen beim Definieren der Sammlungsklasse überladen
initialisieren: function() {
},
// Ein Array zurückgeben, das die Datenobjekte jedes Modells in der Sammlung enthält
toJSON: Funktion(Optionen) {
// Verwenden Sie die Kartenmethode von Undersocre, um ein Array von toJSON-Ergebnissen für jedes Modell in der Sammlung zu bilden und zurückzugeben
return this.map(function(model) {
// Rufen Sie nacheinander die toJSON-Methode jedes Modellobjekts auf. Diese Methode gibt standardmäßig das Datenobjekt des Modells (kopierte Kopie) zurück.
// Wenn Sie eine Zeichenfolge oder andere Formen zurückgeben müssen, können Sie die toJSON-Methode überladen
return model.toJSON(options);
});
},
//Ein oder mehrere Modellobjekte zur Sammlung hinzufügen
// Das „add“-Ereignis wird standardmäßig ausgelöst. Wenn das Silent-Attribut in den Optionen festgelegt ist, kann diese Ereignisauslösung deaktiviert werden.
// Die übergebenen Modelle können ein oder mehrere Modellobjekte (Instanzen der Model-Klasse) sein. Wenn das Modellattribut in der Sammlung festgelegt ist, sind Datenobjekte (z. B. {name: 'test'}) zulässig Direkt übergeben: Das Datenobjekt wird automatisch in das Modellobjekt instanziiert, auf das das Modell zeigt
hinzufügen: Funktion(Modelle, Optionen) {
//Lokale Variablendefinition
var i, index, length, model, cid, id, cids = {}, ids = {}, dups = [];
Optionen ||. ( Optionen = {});
// Modelle müssen ein Array sein. Wenn nur ein Modell übergeben wird, konvertieren Sie es in ein Array
models = _.isArray(models) ? models.slice() : [models];
// Durchlaufen Sie die Liste der Modelle, die hinzugefügt werden müssen. Während des Durchlaufvorgangs werden die folgenden Vorgänge ausgeführt:
// - Datenobjekt in Modellobjekt konvertieren
// - Stellen Sie eine Referenz zwischen dem Modell und der Sammlung her
// – Ungültige und doppelte Modelle protokollieren und später filtern
for( i = 0, length = models.length; i < length; i ) {
// Konvertieren Sie das Datenobjekt in ein Modellobjekt, nehmen Sie die Referenz des Modells und der Sammlung wieder auf und speichern Sie es im Modell (gleichzeitig wurde das entsprechende Modell in Modellen durch ein Modellobjekt ersetzt).
if(!( model = models[i] = this._prepareModel(models[i], Optionen))) {
throw new Error("Ein ungültiges Modell kann nicht zu einer Sammlung hinzugefügt werden");
}
//Cid und ID des aktuellen Modells
cid = model.cid;
id = model.id;
//Ungültige oder doppelte Modellindizes (Indizes im Models-Array) werden im Dups-Array aufgezeichnet und im nächsten Schritt gefiltert und gelöscht.
// Wenn der Index des Modells bereits in den Variablen cids und ids vorhanden ist, wird davon ausgegangen, dass dasselbe Modell im übergebenen Modellarray mehrmals deklariert wurde.
// Wenn der Index des Modells bereits im _byCid-, _byId-Objekt vorhanden ist, wird davon ausgegangen, dass dasselbe Modell in der aktuellen Sammlung bereits vorhanden ist.
// Zeichnen Sie in den beiden oben genannten Situationen den Index des Modells in Dups auf, um ihn zu filtern und zu löschen
if(cids[cid] || this._byCid[cid] || ((id != null) && (ids[id] || this._byId[id]))) {
dups.push(i);
weitermachen;
}
// Zeichnen Sie die durchlaufenen Modelle in Modellen auf, um sie im nächsten Zyklus erneut zu überprüfen
cids[cid] = ids[id] = Modell;
}
// Ungültige oder doppelte Modelle aus Modellen löschen und die Liste der Modelle beibehalten, die wirklich zur aktuellen Sammlung hinzugefügt werden müssen.
i = dups.length;
while(i--) {
models.splice(dups[i], 1);
}
// Durchlaufen Sie die Modelle, die hinzugefügt werden müssen, überwachen Sie Modellereignisse und zeichnen Sie die Liste _byCid und _byId auf, die beim Aufruf der Methoden get und getByCid als Index verwendet wird.
for( i = 0, length = models.length; i < length; i ) {
// Alle Ereignisse im Modell abhören und die Methode _onModelEvent ausführen
// Die _onModelEvent-Methode verarbeitet die vom Modell ausgelösten Ereignisse zum Hinzufügen, Entfernen, Zerstören und Ändern, um das Modell mit dem Status in der Sammlung synchron zu halten.
(model = models[i]).on('all', this._onModelEvent, this);
// Zeichnen Sie das Modell basierend auf cid im _byCid-Objekt auf, um die Suche basierend auf cid zu erleichtern
this._byCid[model.cid] = model;
//Zeichnen Sie das Modell basierend auf der ID im _byId-Objekt auf, um die Suche basierend auf der ID zu erleichtern
if(model.id != null)
this._byId[model.id] = model;
}
//Ändern Sie das Längenattribut der Sammlung. Das Längenattribut zeichnet die Anzahl der Modelle in der aktuellen Sammlung auf.
this.length = Länge;
//Legen Sie die Position fest, an der die neue Modellliste in die Sammlung eingefügt wird. Wenn der Parameter at in den Optionen festgelegt ist, fügen Sie ihn an der Position at der Sammlung ein.
// Wird standardmäßig am Ende der Sammlung eingefügt
// Wenn eine benutzerdefinierte Komparator-Sortiermethode festgelegt ist, wird nach dem Festlegen von at auch nach der Methode im Komparator sortiert, sodass die endgültige Reihenfolge möglicherweise nicht an der durch at angegebenen Position liegt
index = options.at != null ? options.at : this.models.length;
splice.apply(this.models, [index, 0].concat(models));
// Wenn die Komparatormethode festgelegt ist, werden die Daten gemäß dem Algorithmus im Komparator sortiert
// Die automatische Sortierung verwendet das Silent-Attribut, um zu verhindern, dass das Reset-Ereignis ausgelöst wird.
if(this.comparator)
this.sort({
still: wahr
});
// Das Ereignis „add“ nacheinander für jedes Modellobjekt auslösen. Wenn das Silent-Attribut festgelegt ist, verhindern Sie, dass das Ereignis ausgelöst wird.
if(options.silent)
gib dies zurück;
// Durchlaufen Sie die neu hinzugefügte Modellliste
for( i = 0, length = this.models.length; i < length; i ) {
if(!cids[( model = this.models[i]).cid])
weitermachen;
Optionen.index = i;
// Das „Add“-Ereignis des Modells auslösen, da die Sammlung auf das „All“-Ereignis des Modells lauscht, sodass die Sammlung in der _onModelEvent-Methode auch das „Add“-Ereignis auslöst
// Detaillierte Informationen finden Sie in der Methode Collection.prototype._onModelEvent
model.trigger('add', model, this, options);
}
gib dies zurück;
},
//Modellobjekte aus der Sammlung entfernen (unterstützt das Entfernen mehrerer Modelle)
// Die übergebenen Modelle können das Modellobjekt sein, das entfernt werden muss, oder die CID des Modells und die ID des Modells
// Durch das Entfernen des Modells wird die Zerstörungsmethode des Modells nicht aufgerufen
// Wenn der Parameter „options.silent“ nicht festgelegt ist, wird das Entfernungsereignis des Modells und das Entfernungsereignis der Sammlung ausgelöst (die Sammlung lauscht über die Methode _onModelEvent auf alle Ereignisse des Modells).
entfernen: Funktion(Modelle, Optionen) {
var i, l, Index, Modell;
// Optionen sind standardmäßig ein leeres Objekt
Optionen ||. ( Optionen = {});
// Modelle müssen vom Array-Typ sein. Wenn nur ein Modell entfernt wird, fügen Sie es in ein Array ein
models = _.isArray(models) ? models.slice() : [models];
// Durchlaufen Sie die Liste der Modelle, die entfernt werden müssen
for( i = 0, l = models.length; i < l; i ) {
// Die übergebene Modellliste kann das Modellobjekt sein, das entfernt werden muss, oder die CID des Modells und die ID des Modells
// (In den Methoden getByCid und get kann das Modell über cid und id abgerufen werden. Wenn ein Modellobjekt übergeben wird, wird das Modell selbst zurückgegeben.)
model = this.getByCid(models[i]) || this.get(models[i]);
//Das Modell wurde nicht erhalten
if(!model)
weitermachen;
// Entfernen Sie die ID-Referenz des Modells aus der _byId-Liste
delete this._byId[model.id];
// Entfernen Sie die CID-Referenz des Modells aus der _byCid-Liste
delete this._byCid[model.cid];
// indexOf ist eine Methode im Underscore-Objekt. Hier wird die indexOf-Methode verwendet, um die Position zu ermitteln, an der das Modell zum ersten Mal in der Sammlung erscheint.
index = this.indexOf(model);
//Entferne das Modell aus der Sammlungsliste
this.models.splice(index, 1);
//Setzen Sie die Längeneigenschaft der aktuellen Sammlung zurück (zeichnen Sie die Anzahl der Modelle in der Sammlung auf)
this.length--;
// Wenn das Silent-Attribut nicht gesetzt ist, wird das Remove-Ereignis des Modells ausgelöst.
if(!options.silent) {
//Fügen Sie die Position des aktuellen Modells in der Sammlung zum Optionsobjekt hinzu und übergeben Sie sie an das Remove-Listening-Ereignis, damit es in der Ereignisfunktion verwendet werden kann
Optionen.index = index;
model.trigger('remove', model, this, options);
}
//Lösen Sie die Beziehung zwischen dem Modell und der Sammlung auf, einschließlich Verweisen auf das Modell und der Ereignisüberwachung in der Sammlung
this._removeReference(model);
}
gib dies zurück;
},
//Modellobjekt am Ende der Sammlung hinzufügen
// Wenn die Komparator-Sortiermethode in der Sammlungsklasse definiert ist, werden die über die Push-Methode hinzugefügten Modelle gemäß dem vom Komparator definierten Algorithmus sortiert, sodass die Reihenfolge der Modelle geändert werden kann.
push: Funktion(Modell, Optionen) {
// Instanziieren Sie das Modell über die _prepareModel-Methode in ein Modellobjekt. Dieser Code ist redundant, da das Modell auch über _prepareModel in der unten aufgerufenen Add-Methode abgerufen wird.
model = this._prepareModel(model, options);
// Rufen Sie die Add-Methode auf, um das Modell zur Sammlung hinzuzufügen (standardmäßig wird es am Ende der Sammlung hinzugefügt).
this.add(Modell, Optionen);
Rückgabemodell;
},
//Entferne das letzte Modellobjekt in der Sammlung
pop: Funktion(Optionen) {
// Holen Sie sich das letzte Modell in der Sammlung
var model = this.at(this.length - 1);
//Entferne das Modell über die Remove-Methode
this.remove(model, options);
Rückgabemodell;
},
//Fügen Sie das Modell an der ersten Position der Sammlung ein
// Wenn die Komparator-Sortiermethode in der Sammlungsklasse definiert ist, werden die über die Unshift-Methode hinzugefügten Modelle gemäß dem vom Komparator definierten Algorithmus sortiert, sodass die Reihenfolge der Modelle geändert werden kann.
unshift: Funktion(Modell, Optionen) {
// Instanziieren Sie das Modell über die Methode _prepareModel in ein Modellobjekt
model = this._prepareModel(model, options);
//Rufen Sie die Add-Methode auf, um das Modell an der ersten Position der Sammlung einzufügen (auf 0 gesetzt)
// Wenn die Komparator-Sortiermethode definiert ist, wird die Reihenfolge der Sammlung neu geordnet
this.add(model, _.extend({
bei: 0
}, Optionen));
Rückgabemodell;
},
// Entfernen Sie das erste Modellobjekt in der Sammlung und geben Sie es zurück
Verschiebung: Funktion(Optionen) {
// Holen Sie sich das erste Modell in der Sammlung
var model = this.at(0);
//Entferne das Modell aus der Sammlung
this.remove(model, options);
// Modellobjekt zurückgeben
Rückgabemodell;
},
//Suchen Sie das Modell aus der Sammlung basierend auf der ID und geben Sie es zurück
get: function(id) {
if(id == null)
zurückkehren
ungültig 0;
return this._byId[id.id != null ? id.id : id];
},
//Suchen Sie das Modell aus der Sammlung basierend auf cid und geben Sie es zurück
getByCid: function(cid) {
return cid && this._byCid[cid.cid ||.
},
// Finden Sie das Modell aus der Sammlung anhand des Index (Index, beginnend bei 0) und geben Sie es zurück
at: function(index) {
return this.models[index];
},
// Filtern Sie die Modelle in der Sammlung basierend auf Werten
// attrs ist ein Filterobjekt, z. B. {name: 'Jack'}, das alle Modelle (Array) mit dem Namen „Jack“ in der Sammlung zurückgibt
wobei: function(attrs) {
// Attribute dürfen nicht leer sein
if(_.isEmpty(attrs))
zurückkehren [];
// Filtern Sie die Modelle in der Sammlung mithilfe der Filtermethode
// Die Filtermethode ist eine Methode in Underscore, mit der die Elemente in der Sammlung durchlaufen und die Elemente, die die Prozessorüberprüfung bestehen können (Rückgabewert ist wahr), als Array zurückgegeben werden
return this.filter(function(model) {
// Durchlaufe die Validierungsregeln im attrs-Objekt
for(var key in attrs) {
// Passen Sie die Validierungsregeln in attrs an die Modelle in der Sammlung an
if(attrs[key] !== model.get(key))
return false;
}
return true;
});
},
// Sortieren Sie die Modelle in der Sammlung gemäß der durch das Komparatorattribut angegebenen Methode
// Wenn der Silent-Parameter in den Optionen nicht gesetzt ist, wird das Reset-Ereignis nach der Sortierung ausgelöst
Sortieren: Funktion(Optionen) {
// Optionen sind standardmäßig ein Objekt
Optionen ||. ( Optionen = {});
// Das Komparatorattribut (Sortieralgorithmus-Methode) muss beim Aufruf der Sortiermethode angegeben werden, andernfalls wird ein Fehler ausgegeben
if(!this.comparator)
throw new Error('Ein Satz kann nicht ohne Komparator sortiert werden');
//boundComparator speichert die Methode des Komparator-Sortieralgorithmus, die an das aktuelle Sammlungskontextobjekt gebunden ist.
varboundComparator = _.bind(this.comparator, this);
if(this.comparator.length == 1) {
this.models = this.sortBy(boundComparator);
} anders {
//Rufen Sie Array.prototype.sort auf, um die Daten mithilfe des Komparatoralgorithmus benutzerdefiniert zu sortieren
this.models.sort(boundComparator);
}
// Wenn der Silent-Parameter nicht angegeben ist, wird das Reset-Ereignis ausgelöst
if(!options.silent)
this.trigger('reset', this, Optionen);
gib dies zurück;
},
// Die attr-Attributwerte aller Modelle in der Sammlung in einem Array speichern und zurückgeben
zupfen: function(attr) {
// Map ist eine Methode in Underscore, mit der eine Sammlung durchlaufen und die Rückgabewerte aller Prozessoren als Array zurückgegeben werden
return _.map(this.models, function(model) {
// Den attr-Attributwert des aktuellen Modells zurückgeben
return model.get(attr);
});
},
//Ersetze alle Modelldaten (Modelle) in der Sammlung
// Dieser Vorgang löscht alle aktuellen Daten und Status in der Sammlung und setzt die Daten auf Modelle zurück
// Modelle sollten ein Array sein, das eine Reihe von Modellmodellobjekten oder Originalobjekten enthalten kann (wird automatisch als Modellobjekte in der Add-Methode erstellt)
zurücksetzen: Funktion(Modelle, Optionen) {
// models ist das zu ersetzende Modell- (oder Daten-)Array
Modelle ||. ( Modelle = []);
// Optionen sind standardmäßig ein leeres Objekt
Optionen ||. ( Optionen = {});
// Durchlaufen Sie die Modelle in der aktuellen Sammlung, löschen Sie nacheinander ihre Referenzbeziehungen mit der Sammlung und geben Sie sie frei
for(var i = 0, l = this.models.length; i < l; i ) {
this._removeReference(this.models[i]);
}
//Sammlungsdaten löschen und Status zurücksetzen
this._reset();
//Fügen Sie der Sammlung über die Add-Methode neue Modelldaten hinzu
// Hier wird das Konfigurationselement über die exnted-Methode in ein neues Objekt überschrieben. Der standardmäßige stille Wert dieses Objekts ist true, sodass das Ereignis „add“ nicht ausgelöst wird.
// Wenn das Silent-Attribut beim Aufruf der Reset-Methode nicht gesetzt ist, wird das Reset-Ereignis ausgelöst. Wenn es auf „true“ gesetzt ist, wird kein Ereignis ausgelöst. Wenn es auf „false“ gesetzt ist, werden die Ereignisse „add“ und „reset“ ausgelöst der Reihe nach.
this.add(models, _.extend({
still: wahr
}, Optionen));
// Wenn beim Aufruf der Reset-Methode das Silent-Attribut nicht gesetzt ist, wird das Reset-Ereignis ausgelöst.
if(!options.silent)
this.trigger('reset', this, Optionen);
gib dies zurück;
},
// Die Initialisierungsdaten der Sammlung vom Server abrufen
// Wenn der Parameter add=true in den Optionen festgelegt ist, werden die erhaltenen Daten an die Sammlung angehängt, andernfalls werden die aktuellen Daten in der Sammlung durch die vom Server zurückgegebenen Daten ersetzt
fetch: Funktion(Optionen) {
//Kopieren Sie das Optionsobjekt, da das Optionsobjekt später zur temporären Speicherung von Daten geändert wird
Optionen = Optionen ? _.clone(Optionen): {};
if(options.parse === undefiniert)
Optionen.parse = true;
// Sammlung zeichnet das aktuelle Sammlungsobjekt zur Verwendung in der Erfolgsrückruffunktion auf
var-Sammlung = this;
// Benutzerdefinierte Rückruffunktion. Nachdem die Datenanforderung erfolgreich war und das Hinzufügen abgeschlossen ist, wird die benutzerdefinierte Erfolgsfunktion aufgerufen
var success = options.success;
// Bei erfolgreicher Datenanforderung vom Server „options.success“ ausführen. Diese Funktion analysiert und fügt Daten hinzu.
options.success = function(resp, status, xhr) {
// Verwenden Sie die Parse-Methode, um die vom Server zurückgegebenen Daten zu analysieren. Wenn Sie die Datenstruktur anpassen müssen, können Sie die Parse-Methode überladen.
// Wenn in den Optionen add=true festgelegt ist, wird die Add-Methode aufgerufen, um Daten zur Sammlung hinzuzufügen. Andernfalls werden die Daten in der Sammlung durch die vom Server über die Reset-Methode zurückgegebenen Daten ersetzt
Sammlung[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), Optionen);
// Wenn ein benutzerdefinierter Erfolgsrückruf festgelegt ist, führen Sie ihn aus
wenn(Erfolg)
success(collection, resp);
};
// Wenn der Server einen Statusfehler zurückgibt, behandeln Sie das Fehlerereignis über die Methode wrapError
options.error = Backbone.wrapError(options.error, Collection, Optionen);
// Rufen Sie die Backbone.sync-Methode auf, um eine Anfrage zum Abrufen von Daten vom Server zu senden
// Wenn die erforderlichen Daten nicht vom Server abgerufen werden oder die Erfassungsmethode kein AJAX verwendet, können Sie die Backbone.sync-Methode überladen
return (this.sync || Backbone.sync).call(this, 'read', this, options);
},
// Fügen Sie der Sammlung ein Modell hinzu, erstellen Sie es und speichern Sie das Modell auf dem Server
// Wenn Sie ein Modell über ein Datenobjekt erstellen, müssen Sie die Modellklasse deklarieren, die dem Modellattribut in der Sammlung entspricht.
// Wenn das Warteattribut in Optionen deklariert ist, wird das Modell nach erfolgreicher Erstellung des Servers zur Sammlung hinzugefügt. Andernfalls wird das Modell zuerst zur Sammlung hinzugefügt und dann auf dem Server gespeichert (unabhängig davon, ob es gespeichert wird). erfolgreich oder nicht)
erstellen: Funktion(Modell, Optionen) {
var coll = this;
//Optionsobjekt definieren
Optionen = Optionen ? _.clone(Optionen): {};
// Holen Sie sich die Instanz der Modellklasse über _prepareModel
model = this._prepareModel(model, options);
// Modellerstellung fehlgeschlagen
if(!model)
return false;
// Wenn das Wait-Attribut nicht deklariert ist, fügen Sie das Modell über die Add-Methode zur Sammlung hinzu
if(!options.wait)
coll.add(Modell, Optionen);
// Success speichert die benutzerdefinierte Rückruffunktion nach erfolgreichem Speichern auf dem Server (deklariert über options.success)
var success = options.success;
// Hören Sie sich die Rückruffunktion an, nachdem die Modelldaten erfolgreich gespeichert wurden.
options.success = function(nextModel, resp, xhr) {
// Wenn das Warteattribut deklariert ist, wird das Modell der Sammlung erst hinzugefügt, nachdem der Server erfolgreich gespeichert hat.
if(options.wait)
coll.add(nextModel, Optionen);
// Wenn ein benutzerdefinierter Erfolgsrückruf deklariert wird, wird die benutzerdefinierte Funktion ausgeführt, andernfalls wird standardmäßig das Synchronisierungsereignis des Modells ausgelöst
if(success) {
success(nextModel, resp);
} anders {
nextModel.trigger('sync', model, resp, options);
}
};
// Rufen Sie die Speichermethode des Modells auf, um die Modelldaten auf dem Server zu speichern
model.save(null, Optionen);
Rückgabemodell;
},
// Datenanalysemethode, die zum Parsen von Serverdaten in strukturierte Daten verwendet wird, die von Modellen und Sammlungen verwendet werden können
// Standardmäßig wird resp selbst zurückgegeben. Dies muss das vom Backbone unterstützte Datenformat mit dem Server definieren. Wenn Sie das Datenformat anpassen müssen, können Sie die Parse-Methode überladen.
analysieren: function(resp, xhr) {
zurück bzw. zurück;
},
// Chain wird zum Erstellen einer Kettenoperation von Sammlungsdaten verwendet. Sie konvertiert die Daten in der Sammlung in ein Underscore-Objekt und verwendet die Kettenmethode von Underscore, um sie in eine Kettenstruktur umzuwandeln.
// Informationen zur Konvertierungsmethode der Kettenmethode finden Sie in den Kommentaren zur Kettenmethode in Underscore.
Kette: function() {
return _(this.models).chain();
},
//Alle Sammlungselemente löschen und den Datenstatus in der Sammlung zurücksetzen
_reset: Funktion(Optionen) {
//Sammlungselemente löschen
this.length = 0;
this.models = [];
//Sammlungsstatus zurücksetzen
this._byId = {};
this._byCid = {};
},
// Einige Vorbereitungen vor dem Hinzufügen des Modells zur Sammlung
// Einschließlich der Instanziierung der Daten als Modellobjekt und der Referenzierung der Sammlung auf die Sammlungseigenschaft des Modells
_prepareModel: Funktion(Modell, Optionen) {
Optionen ||. ( Optionen = {});
// Prüfen, ob das Modell ein Modellobjekt ist (d. h. eine Instanz der Model-Klasse)
if(!( Modellinstanz von Modell)) {
//Das übergebene Modell ist ein Modelldatenobjekt, kein Modellobjekt
// Daten als Parameter an Model übergeben, um ein neues Modellobjekt zu erstellen
var attrs = Modell;
//Legen Sie die Sammlung von Modellreferenzen fest
options.collection = this;
// Daten in Modell konvertieren
model = new this.model(attrs, options);
// Validieren Sie die Daten im Modell
if(!model._validate(model.attributes, Optionen))
Modell = falsch;
}sonst if(!model.collection) {
// Wenn ein Modellobjekt übergeben wird, aber kein Verweis auf die Sammlung hergestellt wird, setzen Sie die Sammlungseigenschaft des Modells auf die aktuelle Sammlung.
model.collection = this;
}
Rückgabemodell;
},
//Beziehung zwischen einem Modell und der Sammlung aufheben, einschließlich Verweisen auf die Sammlung und Ereignisüberwachung
// Wird im Allgemeinen automatisch aufgerufen, wenn die Remove-Methode zum Löschen des Modells oder die Reset-Methode zum Zurücksetzen des Status aufgerufen wird.
_removeReference: Funktion(Modell) {
// Wenn das Modell auf die aktuelle Sammlung verweist, entfernen Sie die Referenz (Sie müssen sicherstellen, dass alle Referenzen auf das Modell freigegeben wurden, andernfalls wird das Modell möglicherweise nicht aus dem Speicher freigegeben).
if(this == model.collection) {
model.collection löschen;
}
// Alle in der Sammlung überwachten Modellereignisse abbrechen
model.off('all', this._onModelEvent, this);
},
// Wird automatisch aufgerufen, wenn ein Modell zur Sammlung hinzugefügt wird
// Wird verwendet, um die Ereignisse der Modelle in der Sammlung zu überwachen. Wenn das Modell ein Ereignis auslöst (Hinzufügen, Entfernen, Zerstören, Ändern), führt die Sammlung die entsprechende Verarbeitung durch.
_onModelEvent: Funktion(Ereignis, Modell, Sammlung, Optionen) {
// Beim Hinzufügen und Entfernen von Modellereignissen müssen Sie sicherstellen, dass die Sammlung, zu der das Modell gehört, das aktuelle Sammlungsobjekt ist.
if((event == 'add' || event == 'remove') && Collection != this)
zurückkehren;
//Wenn das Modell das Zerstörungsereignis auslöst, wird es aus der Sammlung entfernt
if(event == 'destroy') {
this.remove(model, options);
}
// Wenn die ID des Modells geändert wird, wird der Verweis auf das Modell in der Sammlungsänderung _byId gespeichert, um die Synchronisierung mit der Modell-ID aufrechtzuerhalten und es einfacher zu machen, das Modellobjekt mit der Methode get() abzurufen.
if(model && event === 'change:' model.idAttribute) {
// Holen Sie sich die ID des Modells vor der Änderung und entfernen Sie es basierend auf dieser ID aus der _byId-Liste der Sammlung
delete this._byId[model. previous(model.idAttribute)];
// Die neue ID des Modells als Schlüssel verwenden und den Verweis auf das Modell in der _byId-Liste speichern
this._byId[model.id] = model;
}
// Das dem Modell in der Sammlung entsprechende Ereignis auslösen. Unabhängig davon, welches Ereignis das Modell auslöst, löst die Sammlung das entsprechende Ereignis aus.
// (Wenn beispielsweise ein Modell zu einer Sammlung hinzugefügt wird, wird das Ereignis „Hinzufügen“ des Modells ausgelöst, und in dieser Methode wird auch das Ereignis „Hinzufügen“ der Sammlung ausgelöst.)
// Dies ist sehr nützlich, um Änderungen am Modellstatus in einer Sammlung abzuhören und zu verarbeiten
// Im überwachten Sammlungsereignis wird das Modell, das das entsprechende Ereignis ausgelöst hat, als Parameter an die Überwachungsfunktion der Sammlung übergeben.
this.trigger.apply(this, arguments);
}
});
// Definieren Sie verwandte Methoden für Sammlungsvorgänge in Underscore
//Kopieren Sie eine Reihe von Sammlungsoperationsmethoden in Underscore in das Prototypobjekt der Collection-Klasse
// Auf diese Weise können Sie Underscore-bezogene Sammlungsmethoden direkt über das Sammlungsobjekt aufrufen.
//Die von diesen Methoden beim Aufruf verarbeiteten Sammlungsdaten sind die Modelldaten des aktuellen Sammlungsobjekts.
var-Methoden = ['forEach', 'each', 'map', 'reduce', 'reduceRight', 'find', 'detect', 'filter', 'select', 'reject', 'every', 'all ', 'some', 'any', 'include', 'contains', 'invoke', 'max', 'min', 'sortBy', 'sortedIndex', 'toArray', 'size', 'first', 'initial', 'rest', 'last', 'without', 'indexOf', 'shuffle', 'lastIndexOf', 'isEmpty', 'groupBy'];
// Durchlaufen Sie die Liste der definierten Methoden
_.each(Methoden, Funktion(Methode) {
//Kopieren Sie die Methode in das Prototypobjekt der Collection-Klasse
Collection.prototype[method] = function() {
// Beim Aufruf direkt die Underscore-Methode verwenden, und das Kontextobjekt bleibt das Underscore-Objekt.
// Es ist zu beachten, dass der hier an die Underscore-Methode übergebene Sammlungsparameter this.models ist. Bei Verwendung dieser Methoden handelt es sich also bei dem betriebenen Sammlungsobjekt um die Modelldaten des aktuellen Sammlungsobjekts.
return _[method].apply(_, [this.models].concat(_.toArray(arguments)));
};
});
// Backbone.Router URL-Router
//------------------
// Implementieren Sie einen benutzerdefinierten Router, indem Sie die Backbone.Router-Klasse erben
// Mit dem Router können Sie Routing-Regeln definieren, durch URL-Fragmente navigieren und jede Regel einer Methode zuordnen, die automatisch ausgeführt wird, wenn die URL mit einer bestimmten Regel übereinstimmt.
// Der Router navigiert durch die URL. Die Navigationsmethoden sind in PushState-, Hash- und Listening-Methoden unterteilt (Einzelheiten finden Sie in der Klasse Backbone.History).
// Legen Sie beim Erstellen einer Router-Instanz die Überwachungsmethode fest, die einer bestimmten Routing-Regel entspricht, über options.routes
// Die Routing-Regeln in options.routes sind nach {Regelname: Methodenname} organisiert. Die jeder Routing-Regel entsprechende Methode muss eine deklarierte Methode in der Router-Instanz sein.
// Die durch „options.routes“ definierten Routing-Regeln werden der Reihe nach abgeglichen. Wenn die aktuelle URL von mehreren Regeln abgeglichen werden kann, wird nur die erste übereinstimmende Ereignismethode ausgeführt.
var Router = Backbone.Router = function(options) {
// Optionen sind standardmäßig ein leeres Objekt
Optionen ||. ( Optionen = {});
// Wenn das Routenobjekt (Routing-Regel) in den Optionen festgelegt ist, weisen Sie es dem Routenattribut der aktuellen Instanz zu
// Das Routenattribut zeichnet die Bindungsbeziehung zwischen Routing-Regeln und Ereignismethoden auf. Wenn die URL mit einer bestimmten Regel übereinstimmt, wird die zugehörige Ereignismethode automatisch aufgerufen.
Nach dem Login kopieren