web-dev-qa-db-fra.com

Désactivez ajaxStart () et ajaxStop () pour une demande spécifique

J'utilise .ajaxStart () et .ajaxStop () pour afficher un modal pendant qu'une demande ajax est en cours. (entre le démarrage et l'arrêt)

Maintenant, je voudrais ajouter une fonction longpoll qui continue d'attendre les notifications, similaire à celle dans le coin supérieur gauche de ce site.

Mon problème réside maintenant dans la désactivation de ce modal uniquement pour la demande de longpolling.

Enregistrement de "l'écran de chargement" sur et hors des gestionnaires:

$(document).ajaxStart(handleAjaxStart);
$(document).ajaxStop(handleAjaxStop);

Ma fonction longpoll:

$.ajax({
    timeout: 35000,
    url: longPollUrl,
    success: function(data){
        if(data.queCount) $('#numQueCount').html(data.queCount);
        if(data.queAccept) $('#numQueAccept').html(data.queAccept);
    }, 
    dataType: 'json',
    complete: longpoll
});

J'ai essayé:

$().off('ajaxStart');
$().off('ajaxStop');

..et rattacher les gestionnaires après le début du sondage, mais pas de joie.

J'ai également essayé d'introduire une variable globale dans handleAjaxStart() qui reviendrait à la première ligne de la fonction, mais cela semble tuer complètement l'écran de chargement.

Des idées sur la façon dont cela peut être réalisé?

70
Gung Foo

Je l'ai compris ..

Il y a un attribut dans l'objet d'options .ajax() prend appelé global.

S'il est défini sur false, il ne déclenchera pas l'événement ajaxStart pour l'appel.

$.ajax({
    timeout: 35000,
    url: longPollUrl,
    success: function(data){
        if(data.queCount) $('#numQueCount').html(data.queCount);
        if(data.queAccept) $('#numQueAccept').html(data.queAccept);
    }, 
    global: false,     // this makes sure ajaxStart is not triggered
    dataType: 'json',
    complete: longpoll
});
177
Gung Foo

Après avoir lu toutes les solutions possibles, je veux combiner les réponses.

Solution 1: Lier/Délier

//binding
$(document).bind("ajaxStart.mine", function() {
    $('#ajaxProgress').show();
});

$(document).bind("ajaxStop.mine", function() {
    $('#ajaxProgress').hide();
});

//Unbinding
$(document).unbind(".mine");

C'est une solution dépréciée. Avant jQuery 1.9, les événements globaux d'ajax comme ajaxStart, ajaxStop, ajaxError etc. peuvent être liés à n'importe quel élément. Après jQuery 1.9:

Depuis jQuery 1.9, tous les gestionnaires des événements Ajax globaux jQuery, y compris ceux ajoutés avec la méthode .ajaxStart (), doivent être attachés au document.

Par conséquent, nous ne pouvons pas lier/dissocier ces événements à des espaces de noms personnalisés.

Solution 2: définissez la propriété global sur false

$.ajax({
        url: "google.com",
        type: "GET",
        dataType: "json",
        global: false, //This is the key property.
        success: function (data) {
                   console.log(data);
                },
        error: function (data) {
                   console.log(data);
                }
       });

Cette solution fonctionne pour désactiver ajaxStart()/ajaxStop() événement (s). Cependant, il fait également désactiver ajaxComplete(), ajaxError(), ajaxSend(), ajaxSuccess(). Si vous n'utilisez pas ces événements globaux, cela semble correct, mais lorsque cela est nécessaire, vous devez revenir et changer votre solution pour toutes les pages où vous définissez global: false.

Solution 3: utiliser une variable globale

var showLoadingEnabled = true;
$(document).ready(function () {
    $('#loading')
        .hide()  // at first, just hide it
        .ajaxStart(function () {
            if (showLoadingEnabled) {
                $(this).show();
            }
        })
        .ajaxStop(function () {
            if (showLoadingEnabled) {
                $(this).hide();
            }
        });
});


function justAnotherFunction() {
    window.showLoadingEnabled = false;
    $.ajax({
        url: 'www.google.com',
        type: 'GET',
        complete: function (data) {
            window.showLoadingEnabled = true;
            console.log(data);
        }
    });
}

Les variables globales ne doivent pas être utilisées dans les fichiers javascript. Cependant, c'est la solution la plus simple, je peux trouver.

J'ai préféré la troisième solution pour mon projet.

10
ahmet