tohokuaikiのチラシの裏

技術的ネタとか。

JavaScriptでイベントを遅延して評価させたい

メッセージキューっていうのかな?

jQuerydelegate/bind前提で。

Ajax:Completeのタイミングで評価するのが本来なんだけど、Ajax:Completeは色んなものが絡んでくるのであんまり直接使いたくない。

しかも、あるパーシャルなHTMLは複数の呼び出し元からCallされる可能性がある。

となると、あんまりやりたくないけど、そのパーシャルなHTMLの最後尾に

<script>
$('body').trigger('my_template_is_called_and_loaded');
</script>

みたいな感じで。

ただ、このEventをキャッチしてなにがしたいかというと、そのパーシャルなHTMLに対してイベントリスナーを付けたい。じゃあ、delegateでいいじゃんっていうけど、要するにあるテーブルに対して$(sometable).flexgrid()みたいにjQueryプラグインを付与させるとかいうケース。

こういう場合、DOMはまだ組み込まれてないので?パーシャル内でtriggerしたEventは自身のパーシャル内のDOMはとらえられない。とらえられるような気がするけどなぁ・・・・。

なので、HTML内にスクリプトタグを書くだけでも忸怩たる思いの上にこんなことをしなければならない。

$('body').bind('my_template_is_called_and_loaded', function(e){
    setTimeout(hogehoge, 1);
});

実際にはhogehogeなんてグローバル関数ではなくて、$.proxyとか使うのだけどそれはさておいて。

とりあえず、1msecでも遅らせないとダメ。この場合は既にAjaxはパーシャルHTMLを取りに行ったのは完了してて、あとは中に入れるだけだから、遅らせるのは1msecだけでも十分。

で、本題のやりたいこと

要するに
Event(my_template_is_called_and_loaded)→ Ajax:Complete → なときにだけFireさせたい。

しかも、それはAjax:Completeにひっかけたくないという。

いや、こういうのはありなんだけど。Eventが一連の流れの中で発火したという情報を持ってて取り出せる(しかも、取り出したら取り出したというのは消してくれるメソッドEvent.firedがあるとして)

$('body').bind('ajax:complete', function(e, xhr){
  if (Event.fired(my_template_is_called_and_loaded'))
      hogehoge();
}
});

こういうのをずらっと書くのはそれはそれで「あぁ、Ajax:completeされた際に何が起こってるかわかりやすいな」という。

AjaxCompleteみたいなグローバルなイベント(にたいするListener)はソースコードの中にとっちらかりやすいからまとめたいんですよね。

むつかしいなぁ。