サーバーにキャッシュされたオブジェクトのデータを変更するアプリケーションを書いています。変更は、基本的にそのオブジェクトのプロパティを更新するajax呼び出しを通じて実行されます。ユーザーが作業を完了すると、基本的な「変更を保存」ボタンが表示され、データを保存してキャッシュされたオブジェクトをフラッシュできます。
ユーザーを保護するために、保存されていないサーバーオブジェクトに変更が加えられたときにページから移動しようとすると警告が表示されます。そこで、変更が保存されているかどうかに基づいてtrueまたはfalseを返すIsInitializedというWebサービスメソッドを作成しました。保存されていない場合は、ユーザーにメッセージを表示して、ナビゲーション要求をキャンセルする機会を与えたいと思います。
ここに私の問題があります-呼び出しは正しく機能していますが、ajaxの成功呼び出しでコールバック関数に変数値を設定できないようです。これが私が今持っているコードです。
////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.";
}
}
Successコールバックを不適切な方法で使用しようとしているように思われます。保存されていない変更メッセージに対してユーザーにプロンプトを表示するかどうかを決定できるように、SuccessコールバックにJavaScript変数を設定するにはどうすればよいですか?
先ほど指摘したように、非同期呼び出しを行っています。つまり、メソッドが戻る前に残りのコードが呼び出されます。そのajax呼び出しを使用する方法はありますが、それでもwindow.onunloadイベントをキャッチしますか? (シンクロノスをajaxにすることなく)
アンロードイベントでこの動作が必要になるため、代わりに同期呼び出しを行う必要があります。ただし、呼び出しにかかる時間によってはブラウザウィンドウ/タブがフリーズする可能性がありますが、ユーザーがウィンドウを閉じないように効果的に試みているためです...
追加 async: false
をJSONに追加して、同期呼び出しを行います。
Jqueryページの例:
var html = $.ajax({
url: "some.php",
async: false
}).responseText;
問題は、Ajax呼び出しへのリクエストが非同期であることです。そのため、IsInitializedを確認しているときには、通話はまだ終了していません。
成功関数であなたの行動を明記することをお勧めします。
基本的に、ajaxで同期呼び出しを行うことは、実際には推奨されないほど不可能ではありません。
Ajaxリクエストの成功コールバックを通じてデータオブジェクトのプロパティを設定しようとすると、同様の問題が発生しました。 async: false
を使用しても問題は解決しませんでした。私がやったことは、ajax呼び出しの外でsetTimeout
呼び出しを使用し、タイムアウト値を1に設定することでした。
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);
}
1ミリ秒の遅延があるだけで、世界に大きな違いが生まれました。これがないと、sessionid
プロパティはajax呼び出しの外で設定されませんが、コールバック内のアラートは、設定されていることを示しています。あなたが同様の問題に直面した場合、それは考えるべきことです。
理論的にはイベントを強制終了(falseを返す)してウィンドウを閉じることができますが、一部のユーザーによって設定されたJavaScriptの制限に遭遇し、ウィンドウが閉じない理由についてユーザーを混乱させると思います。したがって、Pawel Krakowiakに同意します。ajax呼び出し自体は同期でなければなりません。
ステータスを確認していることをユーザーに通知し(ポップアップではなく、ウィンドウの上部にある素敵な通知バナーの1つ)、$。ajaxを設定してください。この状況でより適切なものへの「タイムアウト」オプションなので、ウィンドウが閉じるのを彼らが永遠に待つことはありません。
私にとって最良のアプローチは、私のajax呼び出しでasync:falseオプションを使用することでした。私はラシャックがこれをすることをためらっていることを理解していますが、この状況は手段を正当化すると思います。
また、Jerphがステータスを確認しようとしている間、ユーザーがハングアップしないようにすることの重要な点も示しています。タイムアウトオプションと組み合わせることは重要です。
コメントしてくれた皆さん、ありがとう。