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

初心者のためのExtJS入門

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

チュートリアル:ルーティングを使って、SPA(シングルページアプリケーション)にする(1)

今回は、メモ一覧とメモ入力フォームを別の画面に分けて、ルーティングを使って画面遷移できるようにします。

ルーティングは、URLのパターンで処理を切り替える機能です。これを使ってSPAにします。

最終的には、http://localhost:1841/#listにアクセスした場合は一覧画面、http://localhost:1841/#registにアクセスした場合は登録画面を表示するようにしようと思います。

ビューコントローラのroutesコンフィグでルートを定義する

とりあえず、まずルーティングを試してみます。

ルーティングはどのビューコントローラにでも設定できますが、ここでは全体を構成するビューポートのビューコントローラに定義することにしましょう。

ビューポートとそのビューコントローラクラスだけ用意します。

/**
 * ビューポートクラス。
 *
 * @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',

    layout: 'card'
});

/**
 * ビューポートのビューコントローラクラス。
 *
 * @class Memo.view.main.ViewController
 * @extend Ext.app.ViewController
 */
Ext.define('Memo.view.main.ViewController', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.app_main',

    routes: {
        'list': 'onList',
        'regist': 'onRegist'
    },

    onList: function () {
        console.log('#list');
    },

    onRegist: function () {
        console.log('#regist');
    }

});

http://localhost:1841/#listにアクセスすると、コンソールログ#listが出力されました。

このように、ビューコントローラのroutesコンフィグにURLのパターンをキーとして設定したメソッドが呼ばれていることが分かります。

画面を表示してみる

次は具体的に画面を表示してみます。

とりあえず、一覧画面と登録画面をそれぞれMemo.view.list.Panel、Memo.view.regist.Panelとして作成してみます。ビューモデルとビューコントローラの部分は一旦外してシンプルな状態にしておきます。sassも変更に合わせて調整が必要です。

/**
 * メモ一覧パネルクラス。
 *
 * @class Memo.view.list.Panel
 * @extend Ext.Panel
 */
Ext.define('Memo.view.list.Panel', {
    extend: 'Ext.Panel',
    xtype: 'list_panel',

    requires: [
        'Memo.view.list.View'
    ],

    layout: 'fit',

    items: {
        xtype: 'list_dataview'
    }
});

/**
 * メモ一覧データビュークラス。
 *
 * @class Memo.view.list.View
 * @extend Ext.view.View
 */
Ext.define('Memo.view.list.View', {
    extend: 'Ext.view.View',
    xtype: 'list_dataview',

    cls: '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'
});

/**
 * メモ登録フォームパネルクラス。
 *
 * @class Memo.view.regist.Panel
 * @extend Ext.form.Panel
 */
Ext.define('Memo.view.regist.Panel', {
    extend: 'Ext.form.Panel',
    xtype: 'regist_panel',

    bodyPadding: 15,

    title: 'メモ入力フォーム',

    config: {
        /**
         * @cfg {Memo.model.Memo} メモモデル。
         */
        record: null
    },

    defaults: {
        anchor: '100%'
    },

    items: [
        {
            name: 'title',
            xtype: 'textfield',
            emptyText: 'タイトルを入力してください',
            allowBlank: false
        },
        {
            name: 'body',
            xtype: 'textarea',
            emptyText: '本文を入力してください'
        },
        {
            xtype: 'button',
            text: '保存'
        }
    ],

    /**
     * recordコンフィグ設定時の処理。
     * @param {Memo.model.Memo} record メモモデル
     */
    setRecord: function (record) {
        var me = this;

        if (!record) {
            record = Ext.create('Memo.model.Memo');
        }

        me.loadRecord(record);
    }

});

次に画面は動的に作成し、ビューポートに設置させるようにしてみます。

/**
 * ビューポートのビューコントローラクラス。
 *
 * @class Memo.view.main.ViewController
 * @extend Ext.app.ViewController
 */
Ext.define('Memo.view.main.ViewController', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.app_main',

    requires: [
        'Memo.view.list.Panel',
        'Memo.view.regist.Panel'
    ],

    routes: {
        'list': 'onList',
        'regist': 'onRegist'
    },

    onList: function () {
        this.switchScreen('list_panel');
    },

    onRegist: function () {
        this.switchScreen('regist_panel');
    },

    /**
     * 画面を切り替える。
     * @param {String} screenXType 画面のxtype
     */
    switchScreen: function (screenXType) {
        var me = this,
            view = me.getView(),
            screen;

        // 画面の存在チェック
        screen = view.down(screenXType);

        if (!screen) {
            // 画面を生成
            screen = Ext.widget(screenXType);

            // ビューポートに追加
            view.add(screen);
        }

        view.getLayout().setActiveItem(screen);
    }

});

これでhttp://localhost:1841/#listhttp://localhost:1841/#registにアクセスしたら、一覧画面と登録画面が表示されるようになりました。

f:id:sham-memo:20170117112107p:plain

f:id:sham-memo:20170117112114p:plain

一旦ここまで。次回、もう少し細かい部分の実装をしてみます。