jquery Ajax call-définir la valeur de la variable en cas de succès [dupliquer]

Cette question a déjà une réponse ici:

J'ai une application que j'écris qui modifie les données sur un objet mis en cache dans le serveur. Les modifications sont effectuées via un appel ajax qui met à jour essentiellement les propriétés de cet objet. Lorsque l'Utilisateur a terminé de travailler, J'ai un bouton de base "enregistrer les modifications" qui leur permet d'enregistrer les données et de vider l'objet mis en cache.

Afin de protéger l'utilisateur, je veux les avertir si vous essayez de vous éloigner de la page lorsque des modifications ont été apportées à l'objet serveur s'ils n'ont pas été enregistrés. J'ai donc créé une méthode de service web appelée IsInitialized qui retournera true ou false selon que les modifications ont été enregistrées ou non. Si elles n'ont pas été enregistrées, je veux inviter l'utilisateur et lui donner une chance pour annuler leur demande de navigation.

Voici mon problème-bien que les appels fonctionnent correctement, je n'arrive pas à obtenir l'appel ajax success pour définir la valeur de la variable sur sa fonction de rappel. Voici le code que j'ai maintenant.

   ////Catches the users to keep them from navigation off the page w/o saved changes...
window.onbeforeunload = CheckSaveStatus;
var IsInitialized;

function CheckSaveStatus() {

    var temp = $.ajax({
        type: "POST",
        url: "URL.asmx/CheckIfInstanceIsInitilized",
        data: "{}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(result) {
            IsInitialized = result.d;
        },
        error: function(xmlHttpRequest, status, err) {
            alert(xmlHttpRequest.statusText + " " + xmlHttpRequest.status + " : " + xmlHttpRequest.responseText);
        }

    });

    if (IsInitialized) {
        return "You currently have unprocessed changes for this Simulation.";
    }
}

Je pense que je pourrais essayer d'utiliser le rappel de succès d'une manière inappropriée. Comment puis-je définir une variable javascript sur le rappel de succès afin que je puisse décider si oui ou non l'utilisateur doit être invité avec les modifications non enregistrées message?

Comme cela vient d'être souligné, je fais un appel asynchrone, ce qui signifie que le reste du code est appelé avant le retour de ma méthode. Existe-t-il un moyen d'utiliser cet appel ajax, mais toujours attraper la fenêtre.événement onunload? (sans faire synchronos ajax)

37
demandé sur Nathan 2009-04-02 18:11:31

7 réponses

Puisque vous avez besoin de ce comportement dans l'événement unload, vous devrez effectuer un appel synchrone à la place. Cependant, il peut geler la fenêtre/l'onglet du navigateur en fonction de la durée de l'appel, mais parce que vous essayez effectivement d'empêcher l'utilisateur de fermer la fenêtre...

Ajoutez async: false à votre JSON pour effectuer un appel synchrone.

34
répondu Pawel Krakowiak 2009-04-02 14:40:57

Un exemple de page jquery:

var html = $.ajax({
  url: "some.php",
  async: false
 }).responseText;

Source: http://api.jquery.com/jQuery.ajax/

7
répondu Vale 2010-11-14 08:44:13

La chose est que la requête à L'appel Ajax est asynchrone. Donc, au moment où vous vérifiez que vous êtes initialisé, l'appel n'est pas encore terminé.

Je suggère de spécifier votre comportement dans la fonction de réussite.

Fondamentalement, avoir des appels synchrones avec ajax est sinon impossible que vraiment découragé.

4
répondu Rashack 2009-04-02 14:16:40

Vous pourriez théoriquement tuer l'événement (return false) et fermer la fenêtre en cas de succès, mais je pense que vous rencontreriez des restrictions Javascript définies par certains utilisateurs, et aussi les confondre pour savoir pourquoi leur fenêtre ne se ferme pas. Donc, je suis d'accord avec Pawel Krakowiak, l'appel ajax lui-même doit être synchrone.

J'ajouterai que vous voudrez donner à l'utilisateur une notification que vous vérifiez l'état (pas une fenêtre contextuelle, s'il vous plait. une de ces belles bannières de notification en haut de l' fenêtre) et assurez-vous de définir le$.ajax" timeout " option à quelque chose de plus raisonnable pour cette situation, donc ils n'attendent pas éternellement que la fenêtre se ferme.

2
répondu Jerph 2009-04-02 14:49:22

J'ai eu un problème similaire en essayant de définir une propriété pour un objet de données via le rappel de succès d'une requête ajax. L'utilisation de async: false n'a pas non plus résolu mon problème. Ce que j'ai fini par faire était d'utiliser un appel setTimeout en dehors de l'appel ajax, et de définir la valeur de délai d'attente à 1, comme suit:

function getSessionid() {  
    $.ajax({  
        type: 'POST',  
        url: 'getSession.php',  
        dataType: 'text',  
        success: function(result){myData.sessionid = result;},   
        error: function(data) {alert("Error!\n" + data);} 
    });  
    setTimeout(function() {alert('sessionid = ' + myData.sessionid);},1);  
}  

Le fait D'avoir ce délai de 1 milliseconde a fait toute la différence dans le monde. Sans cela, la propriété sessionid ne serait pas définie en dehors de l'appel ajax, bien que les alertes dans le rappel montraient qu'elle était, en effet, d'être ensemble. C'est quelque chose à penser, si vous rencontrez un problème similaire.

2
répondu GeekCaveCreations 2011-07-14 13:41:05

On dirait que la meilleure approche pour moi était d'utiliser l'option async: false Sur mon appel ajax. Bien que je comprenne L'hésitation de Rashack à faire cela, je pense que cette situation justifie les moyens.

Aussi bon point par Jerph pour s'assurer que je ne laisse pas l'utilisateur suspendu pendant que j'essaie de vérifier leur statut. Cela couplé avec l'option timeout est important.

Merci à tous ceux qui ont commenté.

1
répondu Nathan 2009-04-02 15:20:03