wake-up-neo.com

Best Practice zum Speichern einer gesamten Sammlung?

Angenommen, ich besitze eine Sammlung und habe an vielen Modellen Änderungen vorgenommen. Was ist der beste Weg, um alle Änderungen mit einer einzigen HTTP-Anfrage zu speichern?

33
a paid nerd

Normalerweise erledigen REST Backends die Erstellung/Aktualisierung von Einzelinstanzen. Sie müssen dies ändern, um ein Array von Objekten zu akzeptieren.

Auf der Clientseite müssten Sie jedoch direkt zur Backbone.sync-Funktion wechseln

Backbone.sync = function(method, model, options)

In diesem Fall sollte Ihr Modell ein Array von Modellen sein. Die Methode sollte "create" oder "save" sein und die Optionen nehmen die gleichen Optionen wie ein jQuery-Ajax-Aufruf (Fehler, Erfolg usw.).

24
Julien

Ich werde hier das Falsche tun und Wikipedia in Bezug auf richtige RESTful-Praktiken zitieren : aSETauf example.com/resources sollte die gesamte Sammlung durch eine andere Sammlung ersetzen. Darauf basierend haben wir diesen Vertrag aufgeschrieben, als wir die gleichzeitige Bearbeitung mehrerer Elemente unterstützen mussten.

  1. Der Client sendet {"resources": [{resource1},{resource2}]}
  2. Der Server ersetzt die gesamte Sammlung durch die neuen Informationen vom Client und gibt die Informationen zurück, nachdem sie dauerhaft gespeichert wurden: {"resources": [{"id":1,...},{"id":2,...}]}

Wir haben die Serverhälfte des Vertrages in Rails geschrieben, aber hier ist die Clienthälfte (in CoffeeScript, sorry!):

class ChildElementCollection extends Backbone.Collection
  initialize: ->
    @bind 'add', (model) -> model.set('parent_id', @parent.id)

  url: -> "#{@parent.url()}/resources" # let's say that @parent.url() == '/parent/1'
  save: ->
    response = Backbone.sync('update', @, url: @url(), contentType: 'application/json', data: JSON.stringify(children: @toJSON()))
    response.done (models) => @reset models.resources

Ich dachte, dies wäre ein lot, das einfacher zu implementieren ist, als Backbone.sync zu überschreiben. Ein Kommentar zum Code, unsere Sammlungen waren immer untergeordnete Objekte. Dies sollte erklären, warum der Code eine "parent_id" festlegt, wenn ein Objekt zur Sammlung hinzugefügt wird und wie der Stamm der URL die URL des übergeordneten Objekts ist. Wenn Sie Sammlungen auf Stammebene haben, die Sie ändern möchten, entfernen Sie einfach das Geschäft @parent.

12
carpeliam

Sie sollten Backbone.Collection erweitern und ihm eine save()-Methode geben, die jedes seiner Modelle hasChanged() überprüft. 

Dann sollte Backbone.sync aufgerufen werden, was Sie wahrscheinlich um eine benutzerdefinierte Synchronisierungsfunktion erweitern müssen. Wenn Sie eine benutzerdefinierte Backbone.sync-Funktion verwenden, müssen Sie sie unbedingt in Ihrer Sammlung einstellen.

var CollectionSync = function(method, model, [options]) {
    // do similar things to Backbone.sync
}

var MyCollection = Backbone.Collection.extend({
    sync: CollectionSync,
    model: MyModel,
    getChanged: function() {
        // return a list of models that have changed by checking hasChanged()
    },
    save: function(attributes, options) {
        // do similar things as Model.save
    }
});

Ein anderer Ansatz (mit einem Modell zur Darstellung der Sammlung) ist hier: "Wie" zum Speichern einer gesamten Sammlung in Backbone.js - Backbone.sync oder jQuery.ajax?

Ich mag auch https://stackoverflow.com/a/7986982/137067

6
philfreo

Dieser Code fügt dem Prototyp der Sammlung eine neue Methode hinzu, um die Speichermethode der geänderten Modelle aufzurufen. Es hat für mich funktioniert:

Backbone.Collection.prototype.saveAll = function(options) {
 return $.when.apply($, _.map(this.models, function(m) {
   return m.hasChanged() ? m.save(null, options).then(_.identity) : m;
 }));
};

Hauptlink: https://Gist.github.com/julianitor/701c677279bac1529b88

0
juliantoledo