DWRで受信中インジケーター表示をする+受信完了と同時に関数に移る方法


今日バイトっでやったことまとめます。DWRajax受信完了を待って次の処理をしたいときがある。
例えば、以下のようなプログラムを書いたとする

ajaxでサーバーからデータをもってくる
      ↓
もってきたデーターを使ってhtmlを生成する
      ↓
生成したhtmlの要素(buttonやformなど)にイベントを登録する

通常ではajax受信後はcallback関数で処理させて終わりだが、その後もプログラムを続けたいときがあるが(グローバル変数がcallback内からではアクセスできないから外に書くときとか)、そこでバグが発生する。これは、ajaxで持ってくるデータの量や通信速度によって受信が終了する前に次の処理にいってしまうためイベントが登録されないからである。この問題を回避するために、DWRのプロパティか何かで受信状況のstateを取得できないかと思って探してみたんだけど、見つからなかった。。。。。。
しょうがなく、javascriptで以下の2つを実装することにした。

・受信中のインジケータを表示させる
・表示終了と同時に次の処理に移るようする

要するに、画像と連動させて表示終了を受信完了と見て次の処理も進めるてことです。
プログラムは以下のサイトのものを参考に少し修正しました。

受信中のインジケータを表示させる

    • インジケータ オブジェクト


function jsgt_Indicator(src)
{

this.div = setIndicatorDIV(src);
this.indi_append = indi_append;
this.indi_start = indi_start;
this.indi_stop = indi_stop;

this.img = new Image();
this.img.src = src;
//終了フラグ
this.FIN_FLAG = false;

function setIndicatorDIV(src){
// インジケータを出力するdiv
id = "_indicator"+(new Date()).getTime();//idを生成;
this.div = document.createElement("DIV") ;

// インジケータ用DIVのデフォルト値(インスタンスで上書き変更できます)
this.div.style.position = "relative";
this.div.style.top = "0px";
this.div.style.left = "0px";
this.div.style.width = "0px";
this.div.style.height = "0px";
this.div.style.margin = '0px' ;
this.div.style.padding = '0px' ;

return this.div
}

function indi_append(id){
if(typeof document.getElementById(id) != 'object')return;
document.getElementById(id).appendChild(this.div);
}

//インジケータ スタート
function indi_start(){
this.FIN_FLAG = false;
//サイズを与えることで表示する
this.div.style.height ="12px";
this.div.style.width ="auto";
this.div.innerHTML = '<img src="'+this.img.src+'">' ;
}

//インジケータ ストップ
function indi_stop()
{
this.div.style.width ="0px";
this.div.style.height ="0px";
this.div.innerHTML = '' ;
this.FIN_FLAG = true;
}
return this
}

表示終了と同時に次の処理に移るようする

// 監視タイマーのID
var g_IdViser = new Array();
// 監視器のの数
var g_NumViser = 0;
// グローバルカウンタ
var g_i = 0;
function setViser( cond , funcCall , timeVise){
// 条件が満たされれば、タイマーをクリアして関数を呼び出す
strFunc = "" +
"if(" + cond +"){ " +
"clearInterval(g_IdViser[" + g_NumViser + "]);"
+ funcCall + ";" +
"}";
// 監視タイマーをセット ( setInterval)
g_IdViser[g_NumViser] = setInterval( strFunc , timeVise);
g_NumViser++;
}

実装例
インジケータオブジェクトを生成して、スタート/ストップ関数をDWRの前後にはさむことで画像を表示することができます。ここで、インジケータの終了と次の処理を連動させるために、タイマーに次の関数を入れて指定秒ごとにフラグを見て、trueになったら関数の処理を始めるようにします。


<script>
//インジケータインスタンスを生成
var = new jsgt_Indicator('./pleasewait.gif') ;
//インジケータを追加するDIVを指定
window.onload = function(){indi.indi_append("");}
//インジケーター開始
indi.indi_stop();
//1秒ごとにフラグをみて次の処理に移る
setViser("'" + indi.FIN_FLAG + "'","next_func()",1000);

Test.setContent( in_data, function( back_data ){
///////callbackの処理
//

//インジケーター停止
indi.indi_stop();
});

//次の処理の関数
function next_func(){
///////次の処理



}

<!-- 画像を表示する場所-->
<div id="indidiv">

これで、受信完了よりも先行してプログラムは動かなくはなった。てかDWRの何かを使えば、受信完了の値を正確に取得できるはずなんだろうけど分からない。。。。

(参考サイト)
この人たちのおかげです。