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

时间:2022-04-13 08:37:04

**Edited this post because I found the problem is really in the inability of rails to bind to the ajax:success function.

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

***Using rails 3.2.3

***使用rails 3.2.3

Thanks for taking the time to read and try to help.

感谢您抽出宝贵时间阅读并尝试提供帮助。

I am adding a simple fade out function on the ajax:success of an item being deleted, as follows:

我在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.

After this, I wanted to create an object with unobtrusive jQuery when the user adds something, and have working delete buttons on those as well. I made a create.js.erb file that is called after creating a new item - and the creation works fine, but the delete button cannot access the ajax:success event.

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

It does delete the data from the db when clicked, but the .fadeOut is never bound to it, so it doesn't disappear. The create.js.erb is as follows:

单击时它会从数据库中删除数据,但.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();
});

If I change this to bind to the click function, it works, but this doesn't account for a failed ajax call:

如果我将其更改为绑定到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();
    });

So something must be up with binding to the ajax:success after the item is created. You guys have any idea why this might be happening? Do I need to do something special in rails to get the newly rendered item to recognize ajax events? Any direction would be much appreciated!

所以必须要有一些东西与ajax绑定:在创建项目后成功。你们知道为什么会这样吗?我是否需要在rails中执行一些特殊操作以使新呈现的项目识别ajax事件?任何方向将不胜感激!

P.S. The controller for the delete method is below in case anyone might be able to detect a problem there:

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

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

7 个解决方案

#1


18  

The problem sounds like the bind is happening before the element is generated. Try this:

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

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

#2


12  

I had the same issue, because my form handler method returned a plain string. Be sure to render something jQuery can process:

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

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

#3


1  

I've done similar things recently using Rails 3.2.3. I also use

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

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

and it works fine...

它工作得很好......

#4


1  

Even though this is an old question, I have an updated answer for what works out to be the same issue.

虽然这是一个老问题,但我有一个更新的答案,可以解决同样的问题。

As of version 1.9, jQuery will no longer consider an empty repsonse(render nothing: true) to be a success/done. This means that in your controller you should return an empty JSON object instead.

从版本1.9开始,jQuery将不再考虑空的repsonse(渲染无效:true)成功/完成。这意味着在您的控制器中,您应该返回一个空的JSON对象。

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

respond_to do | format | format.json {render:{} .to_json}结束

#5


0  

Check if you get a parse error (or similar) by catching ajax:completed. Check the status argument there. In my case it was a parseerror due to a mimetype mismatch.

通过捕获ajax:completed来检查是否出现解析错误(或类似错误)。检查那里的状态参数。在我的情况下,由于mimetype不匹配,这是一个解析错误。

You can also set a breakpoint in jquery_ujs.js.

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

See also this question jQuery ajax request not triggering JS response

另见这个问题jQuery ajax请求不会触发JS响应

#6


0  

For me it's because we are using slim, and the templates are 'name.slim'. if we change them to 'name.slim.html', the ajax:success fires correctly.

对我而言,这是因为我们使用的是苗条,模板是'name.slim'。如果我们将它们更改为'name.slim.html',则ajax:success会正确触发。

The solution I am using is to add the format to the render declaration in the controller.

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

So we've got something like this:

所以我们有这样的事情:

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

#7


0  

Even it is an old question, none of the answers really helped me as I had a custom confirmation dialog and the ajax:success was triggering on totally different element.

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

In order to find which element is trigered by your ajax in such case, you can first use code:

在这种情况下,为了找到你的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
});

#1


18  

The problem sounds like the bind is happening before the element is generated. Try this:

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

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

#2


12  

I had the same issue, because my form handler method returned a plain string. Be sure to render something jQuery can process:

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

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

#3


1  

I've done similar things recently using Rails 3.2.3. I also use

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

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

and it works fine...

它工作得很好......

#4


1  

Even though this is an old question, I have an updated answer for what works out to be the same issue.

虽然这是一个老问题,但我有一个更新的答案,可以解决同样的问题。

As of version 1.9, jQuery will no longer consider an empty repsonse(render nothing: true) to be a success/done. This means that in your controller you should return an empty JSON object instead.

从版本1.9开始,jQuery将不再考虑空的repsonse(渲染无效:true)成功/完成。这意味着在您的控制器中,您应该返回一个空的JSON对象。

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

respond_to do | format | format.json {render:{} .to_json}结束

#5


0  

Check if you get a parse error (or similar) by catching ajax:completed. Check the status argument there. In my case it was a parseerror due to a mimetype mismatch.

通过捕获ajax:completed来检查是否出现解析错误(或类似错误)。检查那里的状态参数。在我的情况下,由于mimetype不匹配,这是一个解析错误。

You can also set a breakpoint in jquery_ujs.js.

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

See also this question jQuery ajax request not triggering JS response

另见这个问题jQuery ajax请求不会触发JS响应

#6


0  

For me it's because we are using slim, and the templates are 'name.slim'. if we change them to 'name.slim.html', the ajax:success fires correctly.

对我而言,这是因为我们使用的是苗条,模板是'name.slim'。如果我们将它们更改为'name.slim.html',则ajax:success会正确触发。

The solution I am using is to add the format to the render declaration in the controller.

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

So we've got something like this:

所以我们有这样的事情:

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

#7


0  

Even it is an old question, none of the answers really helped me as I had a custom confirmation dialog and the ajax:success was triggering on totally different element.

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

In order to find which element is trigered by your ajax in such case, you can first use code:

在这种情况下,为了找到你的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
});