如何防止ajax请求?

I have the following situation: page displays set of items, when user clicks on item, item details loaded through ajax request. What I want to do is to prevent ajax requests on further clicks, because information is already loaded.

I use jQuery and Rails 3 and my code looks something like this:

# view
- @items.each do |item|
  .item
    = link_to item.name, item_path(item), :remote => true

// js
$(function(){
  $('.item').bind('ajax:success', function(xhr, data, status){
    ...
  });

  $('.item').bind('ajax:before', function(xhr){
    if (...) { // check if data already loaded
       // ???
    }
  });
});

Am I on a right way? Or there is another solution?

You can set a flag like itemsLoaded = false before ajax call. The moment the detail is loaded you can set that flag to itemsLoaded = true. The ajax call should only be performed when if(!itemsLoaded){/* Do ajax to fetch details */}else return;

I think the only thing you can do is to ensure that the click in the item only goes to the ajax function once. Ways to do this:

  • The click event invokes a function that disables the binding of the item

  • If you want to be sure, you do the same in the ajax success function

  • After clicking the item, your function checks if the item info is already there. If it is, then it just returns.

One solution is you could create a boolean value then only make the ajax call if that value is false.

Set a variable in the Ajax:success function like so...

AjaxSuccessVar=0;
$(function(){
    $('.item').bind('ajax:success', function(xhr, data, status){
       AjaxSuccessVar = 1;
});

$('.item').bind('ajax:before', function(xhr){
   if (AjaxSuccessVar==0) { // check if data already loaded
      //then do your ajax function here
   }
});

How about using a .data property as an indicator, e.g.:

  $('.item').bind('ajax:success', function(xhr, data, status){
      $(this).data("loaded", true);

  }).bind('ajax:before', function(xhr){
      if (!$(this).data("loaded")) {
          // data has not been loaded
      } else {
          // do something
      }
  });

EDIT:

Try unbinding the click handler from the item 'trigger' once it has been clicked, e.g.:

$(".item").click(function() {
    $.ajax({ ... });
    $(this).unbind("click");
});

or perhaps upon successful completion of the request ajax:success

  $('.item').bind('ajax:success', function(xhr, data, status){
      $(this).unbind("click");
  });

It turned out that I used wrong callback. The right callback is ajax:beforeSend with the following signature function(event, xhr, settings). To prevent request sending I used xhr.abort() and it works fine.

http://www.alfajango.com/blog/rails-3-remote-links-and-forms/