JQuery Ajax call – Définir la valeur variable en cas de succès

J'ai une application que j'écris qui modifie les données sur un objet mis en cache sur le serveur. Les modifications sont effectuées via un appel ajax qui met à jour les propriétés de cet objet. Lorsque l'utilisateur est en train de fonctionner, j'ai un bouton «Enregistrer les modifications» de base qui leur permet de sauvegarder les données et de rincer l'objet mis en cache.

Afin de protéger l'utilisateur, je souhaite les avertir si vous essayez de naviguer loin de la page lorsque des modifications ont été apportées à l'objet serveur si elles n'ont pas été enregistrées. Donc, j'ai créé une méthode de service Web appelée IsInitialized qui renverra true ou false en fonction de la modification ou non des modifications. S'ils n'ont pas été enregistrés, je souhaite demander à l'utilisateur et leur donner l'occasion d'annuler leur demande de navigation.

Voici mon problème – bien que les appels fonctionnent correctement, je ne parviens pas à obtenir l'appel de succès ajax 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 de 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 l'utilisateur doit ou non être invité avec le message de modification non enregistré?

Comme je l'ai simplement souligné, je fais un appel asynchrone, ce qui signifie que le reste du code est appelé avant que ma méthode ne revienne. Existe-t-il un moyen d'utiliser cet appel ajax, mais toujours l'événement window.ununload? (Sans créer synchronos ajax)

Comme vous avez besoin de ce comportement dans l'événement de déchargement, vous devrez plutôt effectuer un appel synchrone. 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.

Un exemple de jquery page:

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

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

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

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

Essentiellement, les appels synchrones avec ajax sont, sinon impossible, vraiment découragés.

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

J'ajoute que vous voudrez donner à l'utilisateur une notification indiquant que vous vérifiez le statut (pas une fenêtre contextuelle, s'il vous plaît. Une de ces bannières de notification intéressantes en haut de la 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 pour la fermeture de la fenêtre.

J'ai eu un problème similaire en essayant de définir une propriété pour un objet de données à travers le rappel de succès d'une requête ajax. En utilisant async: false n'a pas encore résolu mon problème. Ce que j'ai fini de faire était d'utiliser un appel setTimeout dehors de l'appel ajax et de définir la valeur de délai d'attente à 1, de la manière suivante:

 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); } 

Juste en ayant ce retard de 1 milliseconde 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 aient montré qu'il était, en effet, défini. C'est quelque chose à réfléchir, si vous rencontrez un problème similaire.

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 pour ce faire, je pense que cette situation justifie les moyens.

Un excellent point par Jerph pour vous assurer que je ne laisse pas l'utilisateur suspendu alors que j'essaie de vérifier leur statut. L'option couplée w / timeout est importante.

Merci à tous ceux qui ont commenté.