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

Dav*_*ite 36 javascript ruby-on-rails javascript-framework backbone.js ruby-on-rails-3

我有一个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";
      }
    });
  }
});
Run Code Online (Sandbox Code Playgroud)

当我单击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
Run Code Online (Sandbox Code Playgroud)

这是破坏与Ruby交互的服务器操作(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
Run Code Online (Sandbox Code Playgroud)

以下是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
Run Code Online (Sandbox Code Playgroud)

Der*_*ley 52

@David Tuite评论:

"好吧,我明白了.看来Backbone希望JSON响应是被破坏的记录的JSON序列化.但是,Rails控制器生成器只返回head:默认是ok.我将JSON响应更改为渲染json: @listing_save @listing_save是我刚刚销毁的记录,它注册成功."

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

  • 好的,你可以得到积分.即使我做了一半的工作;) (3认同)
  • 虽然您不必返回模型,但有时这样做很好.实际上这是一个很好的方法的一种情况是当你没有使用destroy的{wait:true}参数时 - 这样,如果操作失败,你可以轻松地将模型重新添加到集合中,以保持集合更新. (2认同)

cca*_*dar 16

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

我的解决方案是使用"text"dataType,可以在选项中设置:

model.destroy({ dataType: "text", success: function(model, response) {
  console.log("success");
}});
Run Code Online (Sandbox Code Playgroud)

  • 我还使用了`model.destroy({contentType:false,processData:false})`. (2认同)

小智 7

您的回复必须包含状态代码204,因为您不会返回任何内容.由于骨干使用REST接口,因此您应根据任务返回不同的http状态代码.