2011年5月15日日曜日

ExtJS-111 ATNDの受付のその後(まとめ)


長々とまとめ。またしばらく触らんだろうからね。

まずお世話になった、なってるリンクは山ほどあるのですが、
http://extjs.blog.sus4.co.jp/
http://www.sunvisor.net/extjs/06
http://extdocs.xenophy.com/
今回は主にこちらにお世話になりました。

あと@naotoriさんのカーセンサーのサンプル。どこに行っちゃったんだろ。。
探せない。。

レイアウトについてはレイアウト迷子になってたときに、
@martini3ozさんにお世話になりました。
こちらはスッと頭に入ってきて良かった。
ツイッターというサービスに感謝。
http://www.sunvisor.net/extjs/06

あと、PDで小堤さんが何気なく
itemsをババっと書いて、layoutをちょこちょこ変えて
例を見せてくれたので「ああ、そうか、そんな感じで変えて試せばいいんだな」って。

みんなPerfectDay行けばいいのに(また言ってる)。

さていろいろ過去の分も含めておさらいを。
(writerについてもまとめておかなきゃ。もう忘れてる。。。)

■CDNについて
ExtJsを提供してくれているのはchacheflyです。ほかは知りませんし、
CDNについてもずいぶん前の勉強会ですが、Extjs勉強会を通してはじめて知りました。

■継承(Ext.util.Observable継承)
    ・constructor
        ・addEvents
        ・on / ・mon
        ・superclass.constructor.apply(me,arguments);  
    な順で。
     

    ex)
    AtndReception.AtndService = Ext.extend(Ext.util.Observable, {
        constructor: function (){
            var me = this;
            //イベント作成(通知用のIF)
            me.addEvents({'eventsearch':true         //イベント検索
                         ,'seteventfee':true         //イベント会費設定
                         ,'usersearch':true          //ユーザ検索
                         ,'showinfo':true            //詳細情報表示
                         ,'updateinfo':true          //情報情報更新      
                         ,'attendance':true          //受付
                         ,'absence':true});          //受付解除
            AtndReception.AtndService.superclass.constructor.apply(me,arguments);                  
            me.init();
        }
    …


■継承(コンポーネント)
    //コンポーネントの初期化
    ・initComponent(construct時にコールされる)
        ・addEvents(イベントの追加)
        ・superclass.initComponent.call(me);
    な順で。

    ex)
    initComponent: function () {
        var me = this;
        AtndReception.EventGrid.superclass.initComponent.apply(me, arguments);
        me.addEvents('beforesearch',
                    'aftersearch');
    },

    ・initEvents(render時にコールされる)
        ・superclass.initEvents.call(me);
        ・on(ハンドラの設定)
        ・mon
        な順で。

    ex)
    initEvents: function () {
        var me = this;
        AtndReception.EventGrid.superclass.initEvents.apply(me, arguments);
        me.on('rowdblclick', function (grid, rowIndex, e) {
            var me = this;
            //イベント会費ダイアログ作成
            me.observer.fireEvent('preseteventfee',me.store.getAt(rowIndex).data);
            me.observer.fireEvent('usersearch',me.store.getAt(rowIndex).data);
        });          
    },
       

■グリッド設定
    ・store設定
        ・proxy設定

            ex)今回DはWebサービスを使用するため同一ドメインポリシに
                引っかかるためScriptTagProxyを使用します。
                APIのパラメタの仕様に合わせて補正する必要があります。
         
            proxy: new Ext.data.ScriptTagProxy({
                url: 'http://api.atnd.org/events/'
            })
            //ロード前のイベントでatndAPIの仕様に合わせて補正する
            me.on('beforeload', function (o, p) {
                p.params.start++;//Atndは1オリジン
                p.params.count = p.params.limit;//パラメタの変更
            });
            //ロード後のイベントで補正したパラメタ情報の書き戻し
            me.on('load', function (o, r, p) {
                p.params.start--;
            });
                 

        ・reader設定
            フィールドを設定する。
            nameがcolModelのdataIndex値と連結、サーバからの返却キー名がnameと違えば
            mappingで結びつける。
         

            ex)
            reader: new Ext.data.JsonReader({  
                fields: [{
                    name: 'event_id',//こっちはExtJsの世界の通り名だよー
                    mapping: 'event_id'//こっちはサーバからの返却名だよー
                }
                     

    ・colModel設定
        dataIndexはbindするレコードのフィールド名
        (=Readerに設定しているfieldsのname。readerは内部でレコード生成する際に
            このfieldを引数に生成するからおなじこと。)
     
        ex)
        colModel: new Ext.grid.ColumnModel([{
            header: 'イベントID',
            dataIndex: 'event_id'//fields:のnameね。
        }
     
    ・tbar(top)設定(検索用のパネルとか設定してみるよ)
    ・bbar(buttom)設定(集計結果とかステータスとか設定してみるよ)


■フォームの出し入れ
    フォームはformPanelから使用することが多いと思う。
    formPanelに内包されているフォームに対して設定したり取得したり。
    http://extjs.blog.sus4.co.jp/2010/04/22/extjs-tutorial-form-baseic/

    取得:
    ex)
        return me.getComponent('setFeePanel').getForm().getValues();
 
    設定
    ex)
        me.getComponent('setFeePanel').getForm().setValues(config);

■レイアウトのスプリットバー
    スプリットバーの移動は
    スプリットバーのエレメントを移動させて(このアニメーションは未検証のままのこしちゃったけど)
    'beforeapply'を発火でやってみた。
    split.el.move(dir, movesize , {duration: 0.25, easing: 'easeBoth', callback: function (el) {
        var me = this;
        //alert('moved!!');                              
    }, scope: me});
    split.fireEvent('beforeapply', me, dir=== 'bottom' ? panel.getHeight() - movesize : panel.height);

■イベントの管理について
コンポーネント同士がお互いのイベントにハンドラ設定してくと
混乱するけど、止む終えないケースはある。この辺はまったくもってよく
わかってないので@kotsutsumiさんや@Mt_blue81さんや、@djodjojpさんから
ヒントを貰い、
今のところは、、、
Application(オブザーバ:Observable継承) → Service(オブザーバ:Observable継承)→Component(Component)
として、
Serviceには機能要件レベルの実装を行い、イベントの追加、ハンドラとして設定
Componentでは、生成時にServiceオブジェクトを渡しておいて、
機能要件レベルの挙動が発生した際はServiceのイベントを発火させることにした。
サービスの主要なものはサービスに集約したかったから。
また、コンポーネント間での小細工や、連動処理はコンポーネント同士で結びついて
良いことにした。
これは
1:一挙動により下位層が一斉に動き出すケース
2:一挙動により上位層が動き出すケース
3:一挙動により同位層が動き出すケース
があったとき、
2,3のケースが多いかなと思ったから。
なんかイイ方法というかベストプラクティスが欲しいよー。

■総括
新しい発見と良い復習になったと思います。
フォームの細かい制御とかその辺はちゃんと作るとき躓くだろうから
その時にでも。そのまえに実践開発ガイド出るのを期待して。
マジですげー手元においておきたい気分です。

早く出ないなぁ。

■これから
次はSenchaに行ってからExtJs4。
でまた階層Gridに戻ろう。

2011年5月12日木曜日

ExtJS-110 ATNDの受付のその後(jsdoit)

どうして公開したらいいかわからんので
ひとまず昨晩jsdoitにアップした。

んだけど、idが気に入らないので
再びアップした。

んだけど、ワンファイルコードで見にくいから
分割したんだけど、アップの仕方がわからないので

結局そのまま放置した。

http://jsdo.it/froggugugugu/tFYj/fullscreen

ひとまず、
ExtJs3はこれで一旦離れよう。
(以前やってた階層グリッドはちょっと寝かしておこう)


SenchaTouchを開始しよう。
@kotsutsumiさん主催のPerfectday(最近ついていけてない)
でExt4について教えてもらったことが今度はSenchaTouchで
生かせればうれしい限りなんだけど。

ほんと、プログラムがかけない体になってきたよ。。。