La migliore pratica per salvare un'intera raccolta?
-
14-11-2019 - |
Domanda
Diciamo che ho una collezione e ho apportato modifiche a molti dei suoi modelli.Qual è il modo migliore per salvare tutte le modifiche utilizzando una singola richiesta HTTP?
Soluzione
Generalmente il supporto dei backend manegge la creazione / aggiornamento dell'istanza singola.Dovresti cambiarlo per accettare una serie di oggetti.
Detto, sul lato client, dovresti andare direttamente alla funzione backbone.sync
Backbone.sync = function(method, model, options)
.
In questo caso il tuo modello dovrebbe essere una serie di modelli.Il metodo dovrebbe essere "Crea" o "Salva" e le opzioni prendono lo stesso tipo di opzioni come chiamata JQuery Ajax (errore, successo, ecc.)
Altri suggerimenti
Farò la cosa sbagliata qui e citerò Wikipedia a riguardo pratiche RESTful adeguate:UN METTERE A example.com/resources
dovrebbe sostituire l'intera collezione con un'altra collezione.Sulla base di ciò, quando abbiamo dovuto supportare la modifica di più elementi contemporaneamente, abbiamo redatto questo contratto.
- Il cliente invia
{"resources": [{resource1},{resource2}]}
- Il server sostituisce l'intera raccolta con le nuove informazioni provenienti dal client e restituisce le informazioni dopo che sono state rese persistenti:
{"resources": [{"id":1,...},{"id":2,...}]}
Abbiamo scritto la metà del contratto relativa al server in Rails, ma ecco la metà del client (in CoffeeScript, scusate!):
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
Pensavo che questo fosse un quantità più facile da implementare rispetto all'override di Backbone.sync.Un commento sul codice: le nostre raccolte sono sempre state oggetti secondari, il che dovrebbe spiegare perché il codice imposta un "parent_id" ogni volta che un oggetto viene aggiunto alla raccolta e in che modo la radice dell'URL è l'URL del genitore.Se hai raccolte a livello di root che desideri modificare, rimuovi semplicemente il file @parent
Attività commerciale.
Dovresti estendere Backbone.Collection
, dandogli un metodo save()
che controllerebbe ciascuno dei suoi modelli hasChanged()
.
Quindi dovrebbe chiamare Backbone.sync
, che probabilmente dovrai estendere un po 'in una funzione di sincronizzazione personalizzata.Se si utilizza una funzione Backbone.sync
personalizzata, assicurati di impostarlo sulla tua raccolta.
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
}
});
.
Un approccio diverso (utilizzando un modello per rappresentare la raccolta) è qui: " Come "per salvare un'intera collezione in backbone.js - backbone.sync o jquery.ajax?
Mi piace anche
Questo codice aggiunge un nuovo metodo al prototipo di raccolta solo per chiamare il metodo di salvataggio di tali modelli che erano cambiati.Ha funzionato per me:
Backbone.Collection.prototype.saveAll = function(options) {
return $.when.apply($, _.map(this.models, function(m) {
return m.hasChanged() ? m.save(null, options).then(_.identity) : m;
}));
};
.
link Gist: https://gist.github.com/julianitor/701c677279BAC1529B88
.