07.DirectStore を xFrameworkPX とともに使う

DirectStore/EditorGridPanel を使ってアプリケーションを作る時の基本的なことを書き留めておきたいと思います。サーバーサイドは,xFrameworkPX を使います。 

サーバーサイド

xFrameworkPXでは,ExtDirect コントローラーとモジュールをつくります。通常の xFrameworkPX の使い方については,ドキュメントに詳しいので,ここでは ExtDirect に関することだけを書きます。

コントローラー

ファイル名:webapp/.extdirect.php

<?php
class extdirect extends xFrameworkPX_Controller_ExtDirect {

    public $direct = array(
        'namespace' => 'Ext.myApp'
    );

    public $modules = array(
        'testdata' => array(
            'conn' => 'default'
        )
    );
}

xFrameworkPX_Controller_ExtDirect を継承したクラスを作ります。このクラスの execute メソッドでは,ExtDirect の API を返します。

4行目で$direct 配列にオプションを設定しています。ここでは namespace に Ext.myApp と設定しています。namespace に何も設定しない場合,サーバーサイドのメソッドは モジュール名.メソッド名 の形式になりますが,namespace を設定すると namespace.モジュール名.メソッド名 の形式になります。個人的には namespace を設定したほうがソースが読みやすくなると思います。

$direct で設定できる他のオプションは次の通りです。

オプション 初期値 備考
url extdirect.html APIのURL。これを変える時は,コントローラーのクラス名とファイル名も一致させる必要があると思います。(きっと)
type remoting  
descriptor Ext.app.REMOTING_API  
namespace (設定なし)  

モジュール

<?php
class testdata extends xFrameworkPX_Model
{
    var $usetable = 'tblData';

    public function getStore()
    {
        $result = $this->get(
            'all',
            array(
                'fields' => array(
                    'id','val1','val2','val3','val4','val5','val6','val7',
                    'val8','val9','val10','val11','val12','val13'
                )
            )
        );
        return array(
            'success' => true,
            'data' => $result,
            'total' => count($result)
        );
    }
}

テストデータのテーブルですので,DBのテーブルを読んできて,それを全部返しています。本当は抽出条件などを指定するところですが,まぁサンプルということで。最後に取得したデータを連想配列にセットしてます。これはDirectStoreの形式に合わせています。

クライアントサイド

Ext.Designerで,StoreとUI部分を作ります。出力されたコードは次のような感じ。

ストア

ファイル名:MyStore.js

MyStore = Ext.extend(Ext.data.DirectStore, {
    constructor: function(cfg) {
        cfg = cfg || {};
        MyStore.superclass.constructor.call(this, Ext.apply({
            storeId: 'MyStore',
            directFn: Ext.myApp.testdata.getStore,
            root: 'data',
            fields: [
                {
                    name: 'id',
                    mapping: 'id',
                    type: 'int'
                },
                {
                    name: 'val1',
                    mapping: 'val1',
                    type: 'int'
                },

                       :
                       :

                {
                    name: 'val13',
                    mapping: 'val13',
                    type: 'int'
                }
            ]
        }, cfg));
    }
});
new MyStore();

directFn のところに namespace.モジュール名.メソッド名 で先程作ったメソッドを設定(Ext.myApp.testdata.getStore)します。root コンフィグには,モジュールでデータをセットした配列のキー(data)をセットします。

UI部分

ファイル名:MyViewport.ui.js

MyViewportUi = Ext.extend(Ext.Viewport, {
    layout: 'border',
    initComponent: function() {
        this.items = [
            {
                xtype: 'editorgrid',
                title: 'My Grid',
                store: 'MyStore',
                region: 'center',
                height: 410,
                ref: 'grdData',
                columns: [
                    {
                        xtype: 'gridcolumn',
                        header: 'id',
                        dataIndex: 'id',
                        sortable: true,
                        width: 100,
                        editor: {
                            xtype: 'textfield'
                        }
                    },
                    {
                        xtype: 'gridcolumn',
                        header: 'val1',
                        dataIndex: 'val1',
                        sortable: true,
                        width: 100,
                        editor: {
                            xtype: 'textfield'
                        }
                    },

                             :
                             :

                    {
                        xtype: 'gridcolumn',
                        header: 'val13',
                        dataIndex: 'val13',
                        sortable: true,
                        width: 100,
                        editor: {
                            xtype: 'textfield'
                        }
                    }
                ]
            }
        ];
        MyViewportUi.superclass.initComponent.call(this);
    }
});

自動生成されたままです。というか Designer で出力された ui.js のファイルは触らないのが約束です。 

ファイル名:MyViewport.js

Ext.Direct.addProvider(Ext.app.REMOTING_API);

MyViewport = Ext.extend(MyViewportUi, {
    initComponent: function() {
        MyViewport.superclass.initComponent.call(this);
        this.on('beforerender', this.onBeforeRender, this);
    },
    onBeforeRender: function () {
        var s = this.grdData.getStore();
        s.load();
    }
}

このファイルは触っても大丈夫です。ここにイベントハンドラなどを書きます。ViewPort の beforerender イベントで,Storeのload()メソッドをコールしています。

起動部分

ファイル名:index.js

Ext.onReady(function() {
    Ext.QuickTips.init();

    var cmp1 = new MyViewport({
        renderTo: Ext.getBody()
    });
    cmp1.show();
});

index.js に Ext.onReady を書きます。

ファイル名:index.html

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>project.xds</title>
    <link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css"/>
</head>
<body>
    <script type="text/javascript" src="extjs/adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="extjs/ext-all-debug.js"></script>
    <!-- Ext Direct API -->
    <script type="text/javascript" src="extdirect.html"></script>
    <!-- /Ext Direct API -->
    <script type="text/javascript" src="js/MyViewport.ui.js"></script>
    <script type="text/javascript" src="js/MyViewport.js"></script>
    <script type="text/javascript" src="js/MyStore.js"></script>
    <script type="text/javascript" src="js/index.js"></script>
</body>
</html>

uiコンポーネントを読み込む前に Ext.Direct API を読み込んでいます。 

MyViewport.js の1行目に Ext.Direct.addProvider(Ext.app.REMOTING_API); を記述しています。この行の記述場所を間違うとStoreの作成に失敗してしまいます。

失敗例:Ext.onReadyの中でコールする。

index.jsの前にMyStore.jsを読み込んでいます。Designerの出力するコードでは,MyStore.jsの最後で,Storeがnewされています。その時点でExt.Directプロバイダが追加されてなければならないのに,それが処理されていないのでエラーになります。

 

トラックバック


URL から "-MoIyadayo" を削除してトラックバックを送信してください。
トラックバックは承認後に表示されます。