土曜日, 2 月 14th, 2009 | Author: djodjo

Ext.Ajax.requestメソッドは非同期通信のみが実装されている。

どうもフォーラムでは、非同期だけでいいのだという派閥が多いらしく、ver2.2.1になってもsyncモードは実装されていない。

でも、結構使いたい場合がある。(自分のプログラミングスキルのせいかもしれないが)

なので、実装してみました。この方法、Extのフォーラムにもでてたんだけど(すみません、フォーラムのどこかは忘れてしました。)まぁ、単純なものです。


2009/3/27 追記
コメントでご指摘いただいた26行目の判断を修正しました。
2009/4/5 追記2
いやーはずい。
先日修正してたときに、確かめてたんですが自分で気づいたけど結局、直してない。orz
コメントでご指摘いただいた26行目の判断を修正しました。

Ext.lib.Ajax.request = function(method, uri, cb, data, options){
    if (options) {
        var hs = options.headers;
        if (hs) {
            for (var h in hs) {
                if (hs.hasOwnProperty(h)) {
                    this.initHeader(h, hs[h], false);
                }
            }
        }
        if (options.xmlData) {
            if (!hs || !hs['Content-Type']) {
                this.initHeader('Content-Type', 'text/xml', false);
            }
            method = (method ? method : (options.method ? options.method : 'POST'));
            data = options.xmlData;
        } else if (options.jsonData) {
            if (!hs || !hs['Content-Type']) {
                this.initHeader('Content-Type', 'application/json', false);
            }
            method = (method ? method : (options.method ? options.method : 'POST'));
            data = typeof options.jsonData == 'object' ? Ext.encode(options.jsonData) : options.jsonData;
        }
    }

    return this[options.async === false ? "syncRequest" : "asyncRequest"](method, uri, cb, data);

};

Ext.lib.Ajax.syncRequest = function(method, uri, callback, postData){
    var o = this.getConnectionObject();

    if (!o) {
        return null;
    } else {
        o.conn.open(method, uri, false);

        if (this.useDefaultXhrHeader) {
            if (!this.defaultHeaders['X-Requested-With']) {
                this.initHeader('X-Requested-With', this.defaultXhrHeader, true);
            }
        }

        if (postData && this.useDefaultHeader && (!this.hasHeaders || !this.headers['Content-Type'])) {
            this.initHeader('Content-Type', this.defaultPostHeader);
        }

        if (this.hasDefaultHeaders || this.hasHeaders) {
            this.setHeader(o);
        }

        o.conn.send(postData || null);
        this.handleTransactionResponse(o, callback);
        return o;
    }
};

一様使い方

Ext.Ajax.request({
   url: 'foo.php',
   success: someFn,
   failure: otherFn,
   async:false,//<-------ここ追加
   headers: {
       'my-header': 'foo'
   },
   params: { foo: 'bar' }
});

ポイント
1.Ext.overrideは使えません。
  Ext.Ajax.requestはスタティックで、実際はExt.data.Connectionのエイリアス。
  なので、直接関数を再定義します。
  というか、気づくのに大分時間がかかった。
  
2.実際には、requestメソッドを上書きするのと、sync処理をするメソッドを追加しただけ。
  これを、ext-all.jsの後に読み込めば、下記のようにして同期モード完成

Category: 未分類
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

6 Responses

  1. これまで非同期だけ絵なんとかやりくりしてたのですけど、どうしても同期が必要になって
    どうすればいいか調べようと思ってググったら一発目で検索にヒットしてとても助かりました。
    26行目の判定は

    [options.async === false ? "syncRequest" : "asyncRequest"]

    とした方が、 async が指定されなかった場合には同期へ流せますね
    既存プログラムを実行したときに全て syncRequest に流れちゃいまして小一時間ほど格闘しました(;´∀`)

  2. おおお!確かに。26行目いけてないですねぇ(汗)
    ご指摘感謝です。ご迷惑かけちゃったみたいで失礼しました。
    なおしまーす。

  3. 反映感謝です^^
    が。。。

    修正していただいたソースの26行目だと { async : false } をパラメータに指定すると
    asyncRequest() に流れちゃうようです(;´∀`)

    1. 三項演算の “asyncRequest” と “syncRequest” を入れ替える

    2. options.async !== false と判断にするか

    のどちらかがよいかと思います^^
    何度ものコメント失礼しましたm(_ _)m

  4. orz
     れいさん、ご指摘感謝です。
     自分にぐったり。

  5. こんにちわ。ext 3.0 beta1でもasyncRequestしかないみたいですね。
    まぁ、僕も非同期で十分派ですが。。。

  6. makoto_kwさん、コメントありがとうございます。
    >ext 3.0 beta1でもasyncRequestしかないみたいですね。
    そうでしたか、まだそこまで見てませんでした。(^^);
    先のExtJS勉強会では、RC1がとれるのは6月頃との話でしたね。3.0関連記事も書いてみようかな。

Leave a Reply