読者です 読者をやめる 読者になる 読者になる

初心者のためのExtJS入門

ExtJSを使うので、ついでにまとめていきます

チュートリアル:モデル、ストアを作成する

ExtJS

今回はモデルとストアを作成します。

これまではデータビューのstoreコンフィグでストアを簡易な形式で設定していましたが、これを別ファイルとして作成することにします。

事前準備

作成する前に、ファイルを整理します。

まずはapp/Application.jsをclassic直下にコピーします。

その後、appディレクトリに配置されているディレクトリ、ファイルをまるごと削除します。

あと、classic/view/main/List.jsも使っていないので削除します。

モデル

モデルはclassic/src/modelディレクトリに作成していきます。

Ext.data.Modelを継承し、モデルに必要なデータの定義はfieldsコンフィグに設定していきます。

/**
 * メモモデルクラス。
 *
 * @class Memo.model.Memo
 * @extend Ext.data.Model
 */
Ext.define('Memo.model.Memo', {
    extend: 'Ext.data.Model',

    fields: [
        {
            name: 'title',
            type: 'string'
        },
        {
            name: 'body',
            type: 'string'
        }
    ]
});

上記のような、メモを表す「メモモデル」を作成してみました。

ストア

ストアはclassic/src/storeディレクトリに作成していきます。

Ext.data.Storeを継承し、使用するモデルとプロキシを設定します。

/**
 * メモストアクラス。
 *
 * @class Memo.store.Memo
 * @extend Ext.data.Store
 */
Ext.define('Memo.store.Memo', {
    extend: 'Ext.data.Store',

    requires: [
        'Memo.model.Memo'
    ],

    model: 'Memo.model.Memo',

    proxy: 'memory',

    data: [
        { title: 'タイトル1', body: '本文1' },
        { title: 'タイトル2', body: '本文2' },
        { title: 'タイトル3', body: '本文3' }
    ]
});

プロキシについて、ざっくり説明します。

ストアはデータを管理するための機能で、データを取得、保存、削除することができます。

取得、保存、削除のような操作をどのような形式で行うかというのがプロキシで決まります。

プロキシの種類としては、Ext.data.proxy.Ajax、Ext.data.proxy.JsonP、Ext.data.proxy.Memory、Ext.data.proxy.LocalStorageなど色々な種類があります(標準で提供されているのはExt.data.proxyパッケージにあるクラスです)。

単純な非同期通信でサーバとデータのやり取りをしたいのであれば、Ext.data.proxy.Ajaxを使います。

上記のコードでは、Ext.data.proxy.Memoryを使っています。これは、特に通信などを行わずメモリ上に残しておくだけになります(そのうち、Ext.data.proxy.LocalStorageに変えるつもりです)。

データビューでストアを使うようにする

まずはアプリケーションクラスのstoreコンフィグに作成したストアを設定します。

/**
 * アプリケーションクラス。
 *
 * @class Memo.Application
 * @extend Ext.app.Application
 */
Ext.define('Memo.Application', {
    extend: 'Ext.app.Application',
    
    name: 'Memo',

    stores: [
        'Memo'
    ]
});

ちなみにストアには「ストアID」という一意となるIDが付与されるようになっています。

自動的に付与されるのはクラス名と同じ文字列です。

最後にデータビューのstoreコンフィグを変更します。

/**
 * ビューポートクラス。
 *
 * @class Memo.view.main.Main
 * @extend Ext.Panel
 */
Ext.define('Memo.view.main.Main', {
    extend: 'Ext.Panel',
    xtype: 'app_main',

    requires: [
        'Memo.view.main.ViewController'
    ],

    cls: 'app-main',

    controller: 'app_main',

    bodyPadding: 20,

    layout: 'border',

    items: [
        {
            region: 'west',
            reference: 'form',
            xtype: 'form',
            title: 'メモ入力フォーム',
            bodyPadding: 15,
            width: 300,
            defaults: {
                anchor: '100%'
            },
            items: [
                {
                    name: 'title',
                    xtype: 'textfield',
                    emptyText: 'タイトルを入力してください',
                    allowBlank: false
                },
                {
                    name: 'body',
                    xtype: 'textarea',
                    emptyText: '本文を入力してください'
                },
                {
                    xtype: 'button',
                    text: '保存',
                    handler: 'onClickSaveButton'
                }
            ]
        },
        {
            region: 'center',
            reference: 'list',
            xtype: 'dataview',
            cls: 'memo-list-dataview',
            tpl: [
                '<tpl for=".">',
                    '<div class="item">',
                        '<h3 class="title">{title}</h3>',
                        '<p class="body">{body}</p>',
                    '</div>',
                '</tpl>'
            ],
            itemSelector: 'div.item',
            store: 'Memo'
        }
    ]
});

これで、ストアを別ファイルに分けることができました。

補足

今回、appディレクトリ以下のファイルを削除しました。これは私の場合ですが、appディレクトリは使用しません。

最初、appにはclassicとmodernの共通処理のコードを作成すると説明しました。自動生成した時点では、ストアとモデルもappに作成するようにディレクトリが用意されています。

しかし、実際の案件で使っていると、classicとmodernでは画面設計が違ったりすることが多く、全く同じストアとモデルを使えないことが多々あるため、最初から分けてしまうことにしています。

共通処理が必要な場合は「パッケージ」を作って、そこに作成するようにしています。