Backbone model.destroy () вызывает функцию обратного вызова ошибки, даже когда она работает нормально? - PullRequest
36 голосов
/ 05 сентября 2011

У меня есть модель Backbone.js , которую я пытаюсь уничтожить, когда пользователь щелкает ссылку в представлении модели.Представление выглядит примерно так (псевдокод, потому что он реализован в CoffeeScript , который можно найти в нижней части вопроса).

var window.ListingSaveView = Backbone.View.extend({
  events: {
    'click a.delete': 'onDestroy'
  },

  onDestroy: function(event){
    event.preventDefault();
    this.model.destroy({
      success: function(model, response){
        console.log "Success";
      },
      error: function(model, response){
        console.log "Error";
      }
    });
  }
});

Когда я нажимаю ссылку delete вв браузере, я всегда получаю Error, зарегистрированный на консоли, даже если мой сервер регистрирует успешное уничтожение связанной записи базы данных и возвращает ответ 200.Когда я обновляю страницу (вызывая повторную визуализацию коллекции из БД), удаленная мною модель исчезает.

Одна интересная вещь заключается в том, что когда я регистрирую response в обратном вызове ошибки, он имееткод состояния 200 указывает на успех, но также сообщает statusText: "parseerror", что бы это ни значило.В логах сервера нет ошибок.

Что я делаю не так?

Это ответ от сервера:

  Object
    abort: function ( statusText ) {
    always: function () {
    complete: function () {
    done: function () {
    error: function () {
    fail: function () {
    getAllResponseHeaders: function () {
    getResponseHeader: function ( key ) {
    isRejected: function () {
    isResolved: function () {
    overrideMimeType: function ( type ) {
    pipe: function ( fnDone, fnFail ) {
    promise: function ( obj ) {
    readyState: 4
    responseText: " "
    setRequestHeader: function ( name, value ) {
    status: 200
    statusCode: function ( map ) {
    statusText: "parsererror"
    success: function () {
    then: function ( doneCallbacks, failCallbacks ) {
    __proto__: Object

Вот действие сервера, котороеУничтожение взаимодействует с (Ruby on Rails)

  # DELETE /team/listing_saves/1.json
  def destroy
    @save = current_user.team.listing_saves.find(params[:id])
    @save.destroy
    respond_to do |format|
      format.json { head :ok }
    end
  end

А вот актуальная реализация BackScript для Backbone View для CoffeeScript:

class MoveOutOrg.Views.ListingSaveView extends Backbone.View
  tagName: 'li'
  className: 'listing_save'
  template: JST['backbone/templates/listing_save']
  events:
    'click a.delete_saved': 'onDestroy'

  initialize: ->
    @model.bind 'change', this.render
  render: =>
    renderedContent = @template(@model.toJSON())
    $(@el).html(renderedContent)
    this
  onDestroy: (event) ->
    event.preventDefault() # stop the hash being added to the URL
    console.log "Listing Destroyed"
    @model.destroy
      success: (model, response)->
        console.log "Success"
        console.log model
        console.log response

      error: (model, response) ->
        console.log "Error"
        console.log model # this is the ListingSave model
        console.log response

Ответы [ 5 ]

52 голосов
/ 05 сентября 2011

@ Комментарий Дэвида Туита:

"Хорошо, я понял это. Похоже, что Backbone ожидает, что ответ JSON будет сериализацией JSON уничтоженной записи. Однако генераторы контроллера Rails возвращают только head: ok по умолчанию. Я изменил свой ответ JSON на render json: @listing_save, где @listing_save - запись, которую я только что уничтожил, и она регистрирует успех. "

К вашему сведению - когда вы делаете уничтожение, вам не нужно возвращать полный JSON для уничтоженной модели. Вы можете вернуть пустой хэш JSON, и он будет работать нормально. единственный раз, когда вам нужно вернуть json для модели, это сохранить / обновить.

16 голосов
/ 25 января 2013

У меня была такая же проблема. В моем методе удаления на сервере (Java) я ничего не возвращал. Просто статус 200 / ОК (или 204 / Нет контента). Таким образом, проблема «parsererror» была вызвана попыткой jquery преобразовать пустой ответ в JSON, что не удалось (поскольку «json» является типом данных по умолчанию).

Мое решение состояло в том, чтобы использовать вместо «text» dataType, который можно установить в опциях:

model.destroy({ dataType: "text", success: function(model, response) {
  console.log("success");
}});
7 голосов
/ 07 декабря 2011

Ваш ответ должен иметь код состояния 204, поскольку вы не будете возвращать контент.Поскольку магистраль использует интерфейс REST, вы должны возвращать различные коды состояния http в зависимости от задачи.

0 голосов
/ 05 июня 2013

Используя Slim Framework на сервере LAMP, вы можете добавить Статус ответа к УДАЛИТЬ маршруты (или пользовательские маршруты, которые ничего не возвращают)

$app->response()->status(204);//204 No Content

это также возвращает Content-Type обратно text / html, чтобы учесть пустое тело

0 голосов
/ 06 сентября 2011

Вы уверены, что ваш URL?Вы добавляете .json в конце URL-адреса Backbone.Model?Поскольку вы проверяете это на своей стороне сервера (response_to do | format | ... end), вы можете не отправлять правильный head :ok response

Попробуйте с помощью этого метода destroy rails проверить, является ли этопроблема:

def destroy
  @save = current_user.team.listing_saves.find(params[:id])
  @save.destroy
  head :ok
end
...