Каков наилучший способ обработки ответа REST API «create» в Backbone.js - PullRequest
12 голосов
/ 21 мая 2011

Я использую backbone.js для взаимодействия с REST API, который при публикации в нем для создания нового ресурса отвечает со статусом 201, заголовком «Location», указывающим на URI ресурса, но пустым телом .

Когда я создаю новую модель в данный момент, она успешна, но локальное представление модели содержит только те свойства, которые я задал явным образом, а не любые свойства, которые будут установлены на сервере (create_date и т. Д.)

Насколько я понимаю, Backbone обновит свое представление модели данными в теле, если они были. Но, поскольку нет, это не так.

Итак, очевидно, что мне нужно использовать местоположение в заголовке Location для обновления модели, но какой лучший способ сделать это.

Мое нынешнее мышление заключается в том, что мне нужно будет проанализировать URL-адрес из заголовка, разделить идентификатор, установить идентификатор для модели, а затем указать модели на получение ().

Это кажется действительно грязным. Есть ли более чистый способ сделать это?

Я имею некоторое влияние на API. Является ли лучшим решением попытаться заставить автора API вернуть новую модель в качестве тела ответа (сохраняя также 201 и заголовок местоположения)?

Спасибо!

Ответы [ 3 ]

7 голосов
/ 24 мая 2011

Звучит так, будто вам придётся немного настроить.Возможно, переопределите метод parse и метод url класса вашей модели, унаследованный от Backbone.Model.

Унаследованные функции:

url : function() {
  var base = getUrl(this.collection);
  if (this.isNew()) return base;
  return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + this.id;
},
parse : function(resp) {
  return resp;
},

, и вы можете попробовать что-то вроде:

parse: function(resp, xhr) {
    this._url = xhr.getResponseHeader('location')
    return resp
}
url: function() {
    return this._url
}
5 голосов
/ 23 мая 2011

Да, backbone.js действительно хочет, чтобы результат сохранения (будь то PUT или POST) был анализируемым телом, которое можно использовать для обновления модели. Если, как вы говорите, у вас есть влияние на API, вы должны увидеть, можете ли вы организовать содержание содержимого атрибутов ресурса.

Как вы указали, нет смысла делать второй вызов по проводной связи, чтобы полностью материализовать модель.

Возможно, код состояния 200 более уместен. Пуристы могут полагать, что код состояния 201 подразумевает, что возвращается только местоположение, а не сущность. Понятно, что в этом случае это не имеет смысла.

2 голосов
/ 26 декабря 2012

С Backbone 0.9.9 я не смог получить принятый ответ на работу.Сигнатура функции parse в старой версии изменилась, и объект xhr больше не доступен в сигнатуре функции.

Это пример того, что я сделал, чтобы сделать егоработать с Backbone v0.9.9 и jQuery 1.8.3 (используя отложенный объект / обещание ), полагаясь на jqXHR объект , возвращаемый Backbone.Model.save():

window.CompanyView = Backbone.View.extend({
// ... omitted other functions...

    // Invoked on a form submit
    createCompany: function(event) {
        event.preventDefault();
        // Store a reference to the model for use in the promise
        var model = this.model;
        // Backbone.Model.save returns a jqXHR object
        var xhr = model.save();
        xhr.done(function(resp, status, xhr) {
            if (!model.get("id") && status == "success" && xhr.status == 201) {
                var location = xhr.getResponseHeader("location");
                if (location) {
                    // The REST API sends back a Location header of format http://foo/rest/companys/id
                    // Split and obtain the last fragment
                    var fragments = location.split("/");
                    var id = fragments[fragments.length - 1];
                    // Set the id attribute of the Backbone model. This also updates the id property
                    model.set("id", id);
                    app.navigate('companys/' + model.id, {trigger: true});
                }
            }
        });
    }
});

Я не использовал обратный вызов success, который можно было бы указать в хеше options, предоставленном функции Backbone.Model.save, поскольку этот обратный вызов вызывается до получения ответа XHR.То есть бессмысленно хранить ссылку на объект jqXHR и использовать ее в обратном вызове success, поскольку jqXHR не будет содержать никаких заголовков ответа (пока) при вызове обратного вызова.

Еще один способ решить эту проблему - написать пользовательскую реализацию Backbone.sync, но я не предпочел такой подход.

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