简体   繁体   中英

Fire Jquery ajax only once, if already fired

I am facing some problems with my Ajax calls. I am working to improve my site's performance, and for that 1 thing I want to do is fire ajax only once, if they have been fired before, not to fire them.

One of My Scenario. I have 2 select drop downs - Country and zones. when a country is changed, .change is fired which fires an ajax to get the zones of the selected country. Now, for eg, If I select country India, Ajax is fired, and change it to Iceland, ajax is fired. Now if i change my country back to india, Ajax should not be fired, as I have already fetched data from server.

CODE

$("#select_list_id").change(function(){
    var url = 'ajax.php?val=' + this.value;
    $.ajax({
      url: url,
      success: function(json){
        for(i=0; i<jsonData.length;i++) {
          $("#select_list_2_id").append(new Option(jsonData[i].title,jsonData[i].id));
        }
      }
    });
  })

My Approach can be to store the json being returned, and compare the countryID on change, if the value already exists, return the json back, else hit the Ajax. But I have near about 100 ajax calls in my project, and this process might take some sweet time.

If anyone can help me, in how to generalize this code.

Apart from all this, while searching I found that this can be done via jquery once plugin as well, if so, can someone please provide some help on this.

Updated - Thanks everyone, this did help me, and things are pretty good now :) Just another small query, what is the use of jquery once plugin then ? Is it used for same stuff ?

if you can generalize your ajax calls, you could cache the result json by the request uri (url+params)

something like this:

var ajaxCache = [];

function ajaxCall(url,successFunc)
{
    if(ajaxCache[url] != undefined)
    {
        successFunc(ajaxCache[url]);
    }
    else
    {
        $.ajax({
            url: url,
                success: function(json){
                    ajaxCache[url] = json;
                successFunc(json);
                }
            });
    }
}

$("#select_list_id").change(function(){
    ajaxCall('ajax.php?val=' + this.value, function(json){
        for(i=0; i<jsonData.length;i++) {
            $("#select_list_2_id").append(new Option(jsonData[i].title,jsonData[i].id));
        }
    });
});

You can store the response on the option that has emitted that request:

$("#select_list_id").change(function() {
    var $selected = $(this).children(":selected");

    if ( $selected.data("json") ) {
        build( $selected.data("json") );
    }
    else {
        $.ajax({
            url: 'ajax.php?val=' + this.value,
            success: function(json) {
                $selected.data("json", json);
                build(json);
            }
        });
    }

    function build(jsonData) {
        for(i=0; i<jsonData.length;i++) {
            $("#select_list_2_id").append(new Option(jsonData[i].title,jsonData[i].id));
        }
    }
});

Assuming that the request is not cached, this is still relatively simple. You would maintain an object with country names as the keys and options as the values:

var countries = {};
.change(...
   var country = this.value;
   if (!countries.hasOwnProperty(country)) {
      countries[country] = [];
      $.ajax ...
         for (var i = 0; ...
            countries[country].push(new Option(...

   }
   //Iteration may be needed
   $("#select_list_2_id").empty().append(countries[country]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM