Backbone model.destroy()调用错误回调函数,即使它工作正常

Backbone model.destroy() invoking error callback function even when it works fine?

本文关键字:工作 函数 回调 destroy model 错误 调用 Backbone      更新时间:2023-09-26

我有一个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链接时,即使我的服务器记录了相关数据库记录的成功销毁并返回200响应,我也总是将Error记录到控制台。当我刷新页面(导致集合从DB重新渲染)时,我删除的模型将消失。

一个有趣的是,当我在错误回调中记录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

这是destroy与(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

下面是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

@David Tuite评论:

"好吧,我明白了。Backbone似乎希望JSON响应是被销毁记录的JSON序列化。但是,Rails控制器生成器默认只返回head:ok。我将JSON响应更改为render JSON: @listing_save其中@listing_save是我刚刚销毁的记录,它注册成功。"

供参考-当你做一个销毁,你不需要返回完整的json被销毁的模型。你可以返回一个空的json散列,它会工作得很好。您唯一需要为模型返回json的时候是在save/update。

我也遇到过同样的问题。在服务器(java)上的删除方法中,我没有返回任何东西。只是状态200/OK(或204/无内容)。因此,"parsererror"问题是由于jquery试图将空响应转换为JSON而失败(因为" JSON "是默认的数据类型)。

我的解决方案是使用"text"数据类型,它可以在选项中设置:

model.destroy({ dataType: "text", success: function(model, response) {
  console.log("success");
}});

您的响应必须具有状态码204,因为您将不返回任何内容。因为backbone使用REST接口,你应该根据任务返回不同的http状态码。

你确定你的URL吗?你是否在主干的末尾附加一个.json ?模型url ?既然你在服务器端检查这个(respond_to do |format|…)end),您可能不会发送正确的head :ok响应

尝试使用destroy rails方法来测试是否存在问题:

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

在LAMP服务器上使用Slim框架,您可以为DELETE路由(或不返回任何内容的自定义路由)添加响应状态

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

这也将Content-Type设置回text/html以允许空正文