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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7305079/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 23:41:17  来源:igfitidea点击:

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

javascriptruby-on-railsruby-on-rails-3backbone.jsjavascript-framework

提问by David Tuite

I have a Backbone.jsmodel that I'm trying to destroy when the user clicks a link in the model's view. The view is something like this (pseudocode because it's implemented in CoffeeScriptwhich can be found at the bottom of the question).

我有一个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";
      }
    });
  }
});

When I click the deletelink in the browser, I always get Errorlogged to the console even though my server records successful destruction of the associated database record and returns a 200 response. When I refresh the page (causing the collection to re-render from the DB) the model I deleted will be gone.

当我单击delete浏览器中的链接时,Error即使我的服务器记录了相关数据库记录的成功销毁并返回 200 响应,我也总是登录到控制台。当我刷新页面(导致集合从数据库重新渲染)时,我删除的模型将消失。

One interesting this is that when I log the responsein the error callback, it has statuscode 200indicating success but it also reports statusText: "parseerror"whatever that means. There is no error in my server logs.

一个有趣的事情是,当我登录response错误回调时,它具有200指示成功的状态代码,但它也会报告statusText: "parseerror"任何含义。我的服务器日志中没有错误。

What am I doing wrong?

我究竟做错了什么?

This is the response from the server:

这是来自服务器的响应:

  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

Here is the server action that destroy interacts with (Ruby on Rails)

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

And here is the actual CoffeeScript implementation of the Backbone View for people who prefer it like that:

这是 Backbone 视图的实际 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

回答by Derick Bailey

@David Tuite comment:

@David Tuite 评论:

"Ok I figured it out. It seems that Backbone expects the JSON response to be a JSON serialization of the record that was destroyed. However, Rails controller generators only return head :ok by default. I changed my JSON response to be render json: @listing_save where @listing_save is the record I just destroyed and it registers a success."

“好吧,我想通了。似乎 Backbone 期望 JSON 响应是已销毁记录的 JSON 序列化。但是,Rails 控制器生成器默认仅返回 head :ok。我将 JSON 响应更改为渲染 json: @listing_save 其中@listing_save 是我刚刚销毁的记录,它注册成功。”

FYI - when you're doing a destroy, you don't need to return the full json for the destroyed model. you can return an empty json hash and it will work just fine. the only time you need to return the json for the model is on a save / update.

仅供参考 - 当您进行销毁时,您无需为销毁的模型返回完整的 json。你可以返回一个空的 json 哈希,它会工作得很好。您唯一需要为模型返回 json 的时间是在保存/更新时。

回答by ccallendar

I had this same problem. In my delete method on the server (java), I didn't return anything. Just status 200/OK (or 204/No content). And so the "parsererror" problem was caused by jquery trying to convert the empty response into JSON, which failed (since "json" is the default data type).

我有同样的问题。在服务器(java)上的删除方法中,我没有返回任何内容。只是状态 200/OK(或 204/无内容)。因此“解析器错误”问题是由 jquery 尝试将空响应转换为 JSON 引起的,但失败了(因为“json”是默认数据类型)。

My solution was to use the "text" dataType instead, which can be set in the options:

我的解决方案是改用“文本”数据类型,它可以在选项中设置:

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

回答by David Rios

Your response must have status code 204 as you won't return any content. Since backbone uses a REST interface you should return different http status codes depending on the task.

您的响应必须具有状态代码 204,因为您不会返回任何内容。由于主干使用 REST 接口,因此您应该根据任务返回不同的 http 状态代码。

回答by Tricote

Are you sure of your URL ? Do you append a .jsonat the end of the Backbone.Model url ? Since you check this on your server side (respond_to do |format| ... end), you might not send the correct head :okresponse

你确定你的网址吗?您是否.json在 Backbone.Model url 的末尾附加了 a ?由于您在服务器端检查了这一点(respond_to do |format| ... end),您可能不会发送正确的head :ok响应

Try with this destroyrails method to test if this is the problem :

尝试使用此destroyrails 方法来测试这是否是问题所在:

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

回答by mhume

Using the Slim Framework on an LAMP server you can add a Response Statusto DELETEroutes (or custom routes that don't return anything)

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

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

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

this also sets the Content-Type back to text/html to allow for the empty body

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