ajax:success和ajax:在Rails中使用UJS时,完全回调不起作用

时间:2013-10-15 15:08:05

标签: jquery ruby-on-rails ajax ujs

我有一个链接,当我点击它将触发ajax调用然后用另一个链接替换此链接,例如原来的链接是“添加朋友”,当我点击此链接时,它将发送一个ajax请求add_friend动作然后如果添加了朋友,上面的链接将被另一个链接“取消请求”替换,我使用ujs:

$("#link_for_friend").html("<%= escape_javascript(render('users/cancel_link')) %>")

当我尝试添加回调(:成功和:完成)时,它不起作用,我尝试使用:beforeSend,如下所示:

$(document).ready ->
  $("#my_link").on "ajax:beforeSend", ->
    alert("hello")

有成功和完全回调的解决方案吗?

注意:我的想法是在ajaxStart被触发时显示loader.gif然后在ajax:至少触发完成回调时隐藏它,如果有一些错误我想在ajax:error被触发时显示它

更新

我尝试通过将action.js.erb中的代码移动到js文件来解决这个问题:

  $(document).ready ->
  $(document).on("ajax:success", "a.invitation-box", ->
    $("#link_for_friend").html("<%= escape_javascript(render('users/cancel_link')) %>")
  ).on "ajax:error", "a.invitation-box", ->
    alert "error"

但是这样就不可能将render('users / cancel_link')放在JS文件中

4 个答案:

答案 0 :(得分:6)

我有同样的问题,问题不在于ajax:success或ajax:完全回调。 问题是,在显示加载gif图像时,您将替换容器的内容,包括链接本身。因此,应用成功的元素,完整的回调不再是DOM的一部分,这就是为什么不会触发回调。

一种解决方案是隐藏元素并附加加载图像,如下所示:

$('#my_link').on "ajax:send", (event, xhr, settings) ->
        $('#my_link').hide()
        $("#my_link_container").append("<image src = 'img.gif' />")

然后将触发成功和完整回调。 希望它可以帮助某人:)

答案 1 :(得分:3)

我相信你的问题归结为JS无法绑定到你的对象,因为它已被更改。 JS的工作方式是将自己“绑定”/“附加”到DOM(文档对象模型)中的元素。 DOM基本上是JS用于调用某些函数的巨大元素列表,因此允许您为这些元素分配各种函数。这就是你可以在不同的元素上调用“点击”功能的方法。

你基本上是替换了你调用Ajax的对象,所以当'ajax:success'发生时,JS无法知道将它关联到哪个对象,从而阻止函数触发

解决这个问题的方法是绑定到文档,然后将绑定委托给div,如下所示:

$(document).on 'ajax:success' , '#my_link', ->
  //do stuff here

这意味着即使这个元素动态变化,它仍然会绑定到它的函数,从而为你提供所需的东西:)

答案 2 :(得分:1)

之前我遇到过这个问题,UJS的ajax:successajax:complete不会被解雇。但其他回调也有效,例如ajax:beforeSend

我的解决方法是使用jQuery的全局事件回调来处理它

$("#my_link").on('ajaxComplete', (evt, data, status, xhr) ->
  alert('This is a jQuery ajax complete event!')

P.S。 UJS使用jQuery的ajax来发送Ajax,所以jQuery的回调肯定会被解雇。

# https://github.com/rails/jquery-ujs/blob/master/src/rails.js
ajax: function(options) {
  return $.ajax(options);
},

答案 3 :(得分:1)

action.js.erb

中试试这个
setTimeout(function () {
  ("#link_for_friend").html("<%= escape_javascript(render('users/cancel_link')) %>")
});

这会将html替换为触发ajax:*事件后发生的下一个计时器滴答。