Wie speichern Sie eine gesamte Sammlung in Backbone.js - Backbone.sync oder jQuery.ajax?



Answers

Eine sehr einfache ...

Backbone.Collection.prototype.save = function (options) {
    Backbone.sync("create", this, options);
};

... geben Ihren Sammlungen eine sichere Methode. Denken Sie daran, dass dies immer alle Modelle der Sammlung auf dem Server ablegt, unabhängig davon, was sich geändert hat. Optionen sind nur normale jQuery AJAX Optionen.

Question

Ich bin mir bewusst, dass es möglich ist, und ich habe mir einige Stellen angeschaut (einschließlich: Best Practice zum Speichern einer ganzen Sammlung? ). Aber ich bin immer noch nicht klar "genau wie" ist es in Code geschrieben? (Der Beitrag erklärt es auf Englisch. Es wäre großartig, eine Javascript-spezifische Erklärung zu haben :)

Angenommen, ich habe eine Sammlung von Modellen - die Modelle selbst können verschachtelte Sammlungen enthalten. Ich habe die toJSON () - Methode der übergeordneten Sammlung außer Kraft gesetzt und erhalte ein gültiges JSON-Objekt. Ich möchte die gesamte Sammlung (entsprechend JSON) "speichern", aber das Backbone scheint nicht mit dieser Funktionalität ausgestattet zu sein.

var MyCollection = Backbone.Collection.extend({
model:MyModel,

//something to save?
save: function() {
   //what to write here?
 }

});

Ich weiß, irgendwo musst du sagen:

Backbone.sync = function(method, model, options){
/*
 * What goes in here?? If at all anything needs to be done?
 * Where to declare this in the program? And how is it called?
 */
}

Sobald die 'Ansicht' mit der Verarbeitung fertig ist, ist sie dafür zuständig, der Sammlung mitzuteilen, dass sie sich selbst auf dem Server "speichern" soll (in der Lage, eine Massenaktualisierungs- / Erstellungsanforderung zu bearbeiten).

Fragen, die auftreten:

  1. Wie / was im Code zu schreiben, um alles "zusammen zu verdrahten"?
  2. Was ist der "richtige" Ort der Rückrufe und wie man einen "Erfolg / Fehler" -Rückruf spezifiziert? Ich meine syntaktisch? Ich bin nicht klar von der Syntax der Registrierung von Rückrufen im Backbone ...

Wenn es in der Tat eine knifflige Aufgabe ist, dann können wir jQuery.ajax in einer Ansicht aufrufen und this.successMethod oder this.errorMethod als Erfolg / Fehler-Callbacks übergeben? Wird es funktionieren?

Ich muss mich mit der Art und Weise des Backbones auseinandersetzen - ich weiß, dass ich definitiv etwas vermisse, wenn man ganze Sammlungen synchronisiert.




Dies hängt wirklich davon ab, was der Vertrag zwischen dem Client und dem Server ist. Hier ist ein vereinfachtes CoffeeScript-Beispiel, bei dem ein PUT zu /parent/:parent_id/children mit {"children":[{child1},{child2}]} die {"children":[{child1},{child2}]} eines Elternteils durch PUT ersetzt und {"children":[{child1},{child2}]} {"children":[{child1},{child2}]} {"children":[{child1},{child2}]} :

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

  url: -> "#{@parent.url()}/children" # 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.children
    return response

Dies ist ein ziemlich einfaches Beispiel, Sie können viel mehr tun ... es hängt wirklich davon ab, in welchem ​​Zustand sich Ihre Daten befinden, wenn save () ausgeführt wird, in welchem ​​Zustand es sein muss, um zum Server zu gelangen und was der Server gibt zurück.

Wenn Ihr Server mit einem PUT von [{child1},{child2] , könnte Ihre Backbone.sync-Zeile in response = Backbone.sync('update', @toJSON(), url: @url(), contentType: 'application/json') .




Die angenommene Antwort ist ziemlich gut, aber ich kann einen Schritt weiter gehen und Ihnen Code geben, der sicherstellt, dass die richtigen Ereignisse für Ihre Listener ausgelöst werden, während Sie auch Optionen für Ajax-Ereignisrückrufe übergeben können:

save: function( options ) {
  var self = this;

  var success = options.success;
  var error = options.error;
  var complete = options.complete;

  options.success = function( response, status, xhr ) {
    self.trigger('sync', self, response, options);
    if (success) return success.apply(this, arguments);
  };

  options.error = function( response, status, xhr ) {
    self.trigger('error', self, response, options);
    if (error) return error.apply(this, arguments);
  };

  options.complete = function( response, status, xhr ) {
    if (complete) return complete.apply(this, arguments);
  }

  Backbone.sync('create', this, options);
}



Ich war auch überrascht, dass Backbone-Kollektionen keinen integrierten Speicher haben. Hier ist, was ich auf meine Backbone-Sammlung zu tun, um es zu tun. Ich möchte definitiv nicht jedes Modell in der Sammlung durchlaufen und unabhängig speichern. Außerdem benutze ich Backbone im Backend unter Verwendung von Node, also überschreibe ich das native Backbone.sync , um es in einer flachen Datei in meinem kleinen Projekt zu speichern - aber der Code sollte ungefähr derselbe sein:

    save: function(){                                                                                                                                                                                                                                                                                                                                                     
      Backbone.sync('save', this, {                                                                                                                                                                                                                                                                                                                                     
        success: function(){                                                                                                                                                                                                                                                                                                                                          
          console.log('users saved!');                                                                                                                                                                                                                                                                                                                              
        }                                                                                                                                                                                                                                                                                                                                                             
      });                                                                                                                                                                                                                                                                                                                                                               
    }



Ich würde etwas versuchen wie:

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
    }
});

( https://.com/a/11085198/137067 )






Links