ajax:success and ajax:complete callback doesn't work when using UJS in Rails

隐身守侯 提交于 2019-12-01 08:28:06

I had the same issue, and the problem is not with ajax:success or ajax:complete callback. The problem is that when displaying the loading gif image, you replace the content of the container, including the link itself. So the element on which you apply the success, complete callback is not part of the DOM anymore, that's why the callback is not fired.

One solution would be to hide the element and append the loading image, like following:

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

Then the success and complete callback will be fired. Hope it helps somebody :)

I believe your problem is down to JS not being able to bind to your object, as it's been changed. The way JS works is to "bind" / "attach" itself to elements in the DOM (Document Object Model). The DOM is basically a huge list of elements JS uses to call certain functions, and thus allows you to allocate various functions to those elements. That's how you can call "click" functions on different elements.

You're basically replacing the object that you've called the Ajax from, so when 'ajax:success' happens, JS has no way to know which object to associate it with, thus preventing the function from firing

The way to get around this is to bind to the document, and then delegate the bind to your div, like this:

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

This means that even if this element changes dynamically, it will still have the function bound to it, thus giving you what you need :)

I met this problem before, UJS's ajax:success and ajax:complete won't be fired. But other callbacks work, such as ajax:beforeSend

My fix is to use jQuery's global event callback to handle it

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

P.S. UJS use jQuery's ajax to send Ajax, so jQuery's callback will surely be fired.

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

Try this in your action.js.erb:

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

This will put the html replacement to the next timer tick that happens after the ajax:* events being triggered.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!