Лучшая практика для сохранения всей коллекции? - PullRequest
33 голосов
/ 16 февраля 2011

Скажите, что у меня есть Коллекция, и я внес изменения во многие ее Модели. Каков наилучший способ сохранить все изменения с помощью одного HTTP-запроса?

Ответы [ 4 ]

24 голосов
/ 16 февраля 2011

Обычно бэкэнды REST обрабатывают создание / обновление одного экземпляра.Вам нужно изменить это, чтобы принимать массив объектов.

Тем не менее, на стороне клиента вам нужно будет перейти непосредственно к функции Backbone.sync

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

В этомВ случае, если ваша модель должна быть массивом модели.Метод должен быть «создать» или «сохранить», и параметры должны иметь параметры того же типа, что и вызов jQuery ajax (ошибка, успех и т. Д.)

12 голосов
/ 03 июля 2012

Я собираюсь сделать неправильную вещь здесь и процитировать Википедию относительно надлежащей практики RESTful : PUT до example.com/resources должно заменить всю коллекцию другой коллекцией. Исходя из этого, когда нам приходилось поддерживать редактирование нескольких элементов одновременно, мы подписали этот контракт.

  1. Клиент отправляет {"resources": [{resource1},{resource2}]}
  2. Сервер заменяет всю коллекцию новой информацией от клиента и возвращает информацию после ее сохранения: {"resources": [{"id":1,...},{"id":2,...}]}

Мы написали серверную половину контракта в Rails, но вот клиентская половина (в CoffeeScript, извините!):

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

Я думал, что это лот проще в реализации, чем переопределение Backbone.sync. Один комментарий к коду: наши коллекции всегда были дочерними объектами, что должно объяснить, почему код устанавливает «parent_id» всякий раз, когда объект добавляется в коллекцию, и как корнем URL является URL родительского объекта. Если у вас есть коллекции корневого уровня, которые вы хотите изменить, просто удалите бизнес @parent.

6 голосов
/ 18 июня 2012

Вы должны расширить Backbone.Collection, предоставив ему метод save(), который будет проверять каждую из его моделей hasChanged().

Тогда он должен вызвать Backbone.sync, который вам, вероятно, придется немного расширить в пользовательскую функцию синхронизации. Если вы используете пользовательскую функцию Backbone.sync, обязательно установите ее в своей коллекции.

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

Здесь используется другой подход (использование модели для представления коллекции): «Как» сохранить всю коллекцию в Backbone.js - Backbone.sync или jQuery.ajax?

Мне тоже нравится https://stackoverflow.com/a/7986982/137067

0 голосов
/ 17 июля 2015

Этот код добавляет новый метод в прототип коллекции, чтобы вызвать метод сохранения тех моделей, которые были изменены.У меня это сработало:

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

Суть ссылки: https://gist.github.com/julianitor/701c677279bac1529b88

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...