Pergunta

Digamos que eu tenha uma coleção e fiz alterações em muitos de seus modelos.Qual é a melhor maneira de salvar todas as alterações usando uma única solicitação HTTP?

Foi útil?

Solução

Normalmente, os back-ends REST lidam com a criação/atualização de instância única.Você precisaria mudar isso para aceitar uma matriz de objetos.

Dito isto, do lado do cliente, você precisaria ir diretamente para a função Backbone.sync

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

Neste caso, seu modelo deve ser uma matriz de modelo.O método deve ser "criar" ou "salvar" e as opções assumem o mesmo tipo de opções que uma chamada jQuery ajax (erro, sucesso, etc.)

Outras dicas

Vou fazer a coisa errada aqui e citar a Wikipedia sobre práticas RESTful adequadas:a COLOCAR para example.com/resources deve substituir toda a coleção por outra coleção.Com base nisso, quando tivemos que suportar a edição de vários itens simultaneamente, redigimos este contrato.

  1. O cliente envia {"resources": [{resource1},{resource2}]}
  2. O servidor substitui toda a coleção pelas novas informações do cliente e retorna as informações após persistirem: {"resources": [{"id":1,...},{"id":2,...}]}

Escrevemos a metade do contrato do servidor em Rails, mas aqui está a metade do cliente (em CoffeeScript, desculpe!):

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

Eu pensei que isso era um muito mais fácil de implementar do que substituir Backbone.sync.Um comentário sobre o código: nossas coleções sempre foram objetos filhos, o que deve explicar por que o código define um "parent_id" sempre que um objeto é adicionado à coleção e como a raiz da URL é a URL do pai.Se você tiver coleções de nível raiz que deseja modificar, basta remover o @parent negócios.

Você deveria estender Backbone.Collection, dando-lhe um save() método que verificaria cada um de seus modelos hasChanged().

Então deveria ligar Backbone.sync, que você provavelmente terá que estender um pouco para uma função de sincronização personalizada.Se você usar um personalizado Backbone.sync função e certifique-se de configurá-la em sua coleção.

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

Uma abordagem diferente (usando um modelo para representar a coleção) está aqui: “Como” salvar uma coleção inteira em Backbone.js – Backbone.sync ou jQuery.ajax?

eu também gosto https://stackoverflow.com/a/7986982/137067

Este código adiciona um novo método ao protótipo da coleção apenas para chamar o método save dos modelos que foram alterados.Funcionou para mim:

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 principal: https://gist.github.com/julianitor/701c677279bac1529b88

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top