jQuery绑定ajax:成功在rails 3应用程序中无法用于新创建的(ajax)项目

Posted

技术标签:

【中文标题】jQuery绑定ajax:成功在rails 3应用程序中无法用于新创建的(ajax)项目【英文标题】:jQuery bind ajax:success not working in rails 3 app for newly created (ajax) items 【发布时间】:2012-07-09 13:05:13 【问题描述】:

**编辑这篇文章是因为我发现问题确实在于 rails 无法绑定到 ajax:success 函数。

***使用rails 3.2.3

感谢您花时间阅读并尝试提供帮助。

我在ajax上添加一个简单的淡出功能:成功删除项目,如下:

$(document).ready( jQuery(function($) 
    $('.delete').bind('ajax:success', function() 
        $(this).closest('div').fadeOut();
    );
));
#For some reason had to pass the $ into the function to get it to work,
#not sure why this is necessary but doesn't work unless that is done.

在此之后,我想在用户添加内容时使用不显眼的 jQuery 创建一个对象,并在这些对象上添加有效的删除按钮。我创建了一个在创建新项目后调用的 create.js.erb 文件 - 并且创建工作正常,但删除按钮无法访问 ajax:success 事件。

单击时它确实会从数据库中删除数据,但 .fadeOut 永远不会绑定到它,因此它不会消失。 create.js.erb如下:

#$("div").append(html) here, then call the function below to try and bind the ajax:success function
$('.delete').bind('ajax:complete', function() 
    $(this).closest('div').fadeOut();
);

如果我将其更改为绑定到 click 函数,它可以工作,但这并不能说明 ajax 调用失败:

#$("div").append(html) here, then call the function below to try and bind the ajax:success function
    $('.delete').bind('click', function() 
        $(this).closest('div').fadeOut();
    );

因此,在创建项目后,必须对 ajax:success 进行绑定。你们知道为什么会发生这种情况吗?我是否需要在 Rails 中做一些特别的事情来让新渲染的项目识别 ajax 事件?任何方向将不胜感激!

附:删除方法的控制器如下,以防任何人在那里检测到问题:

def destroy
    @user = User.find(params[:user_id])
    @item = @user.item.find(params[:id])
    @item.destroy

    respond_to do |format|
      format.html  redirect_to user_path(@user) 
      format.json  head :no_content 
      format.js  render :nothing => true 
    end
end

【问题讨论】:

这是 Rails 3.0.x 还是 3.1/3.2 应用程序? Rails 3.2.3 是我正在使用的版本。很有可能我只是写错了代码,但是,因为你问的是哪个版本的 rails,我不得不问,你知道在早期版本的 rails 或类似的东西中存在这样的错误吗? 有时人们会在同一个项目中激活 jQuery 和 Prototype。在 Rails 3.0.x 中更常见。现在我再次查看它,您可能希望将第二个绑定 (bind_delete_animation) 移动到 document.ready,而不是从 document.ready 调用的函数中。我从来没有成功地绑定在文档之外。 感谢您抽出宝贵时间回来尝试提供帮助。我稍微编辑了堆栈溢出问题。在玩了一些之后,我发现绑定可以工作(例如,如果我绑定到 'click' 事件),问题是它找不到 ajax:success 函数。我确实将绑定直接移动到 document.ready 中,只是为了看看它是否会改变任何东西,并且得到相同的结果。知道为什么 ajax:success 不适用于新创建的项目吗? 关于这个问题的建议都没有对我有用 【参考方案1】:

即使这是一个老问题,没有一个答案真的对我有帮助,因为我有一个自定义确认对话框,并且 ajax:success 触发了完全不同的元素。

为了找到在这种情况下你的ajax触发了哪个元素,你可以先使用代码:

$(document).on('ajax:success', 'a', function(evt, data, status, xhr) 
    $( ".log" ).text( "Triggered ajaxComplete handler." );
    // Check what is the value of $(this), and you will see what button has triggered the ajax success action, and you can start from there
);

【讨论】:

【参考方案2】:

对我来说,这是因为我们使用的是 slim,模板是“name.slim”。如果我们将它们更改为“name.slim.html”,则 ajax:success 会正确触发。

我使用的解决方案是将格式添加到控制器中的渲染声明中。

所以我们有这样的东西:

render :new, layout: false, formats: [:html]

【讨论】:

【参考方案3】:

尽管这是一个老问题,但我有一个更新的答案来解决同样的问题。

从 1.9 版开始,jQuery 将不再将空响应(render nothing: true)视为成功/完成。这意味着在你的控制器中你应该返回一个空的 JSON 对象。

respond_to do |format| format.json render: .to_json end

【讨论】:

【参考方案4】:

通过捕获ajax:completed 检查您是否收到解析错误(或类似错误)。检查那里的status 参数。在我的情况下,由于 mimetype 不匹配,它是 parseerror

您还可以在jquery_ujs.js 中设置断点。

另请参阅此问题jQuery ajax request not triggering JS response

【讨论】:

【参考方案5】:

我最近使用 Rails 3.2.3 做过类似的事情。我也用

$('#dialog-form').bind('ajax:success', function() 
)

而且效果很好……

【讨论】:

其实我发现只要你在你的控制器中渲染一些东西,ajax:success 事件就不会起作用。也许 Rails 也在尝试绑定它。【参考方案6】:

我遇到了同样的问题,因为我的表单处理程序方法返回了一个纯字符串。一定要渲染 jQuery 可以处理的东西:

def handle_form
  ...
  render :json => :what => 'ever'
  # or
  render :nothing => true
end

【讨论】:

对我来说也一样 - 我正在渲染一个纯字符串,但它不起作用。非常感谢。【参考方案7】:

这个问题听起来像是在生成元素之前发生了绑定。试试这个:

$(document).on('ajax:success', '.delete', function(e) 
    $(e.currentTarget).closest('div').fadeOut();
);

【讨论】:

以上是关于jQuery绑定ajax:成功在rails 3应用程序中无法用于新创建的(ajax)项目的主要内容,如果未能解决你的问题,请参考以下文章

rails3 rails.js 和 jquery 捕获 ajax 请求的成功和失败

jquery 不会在 $.ajax 上为 rails 标准 REST DELETE 答案调用成功方法

在 Rails 中使用 will_paginate 和 AJAX 实时搜索和 jQuery

在 Cucumber + Capybara + PhantomJS 在 Rails 中调试 jQuery Ajax

Rails 3.1 ajax:成功处理

jquery ajax post请求不接受绝对url rails应用程序