HOME > 開発者向けBLOG > Ext JS >  Ext JS4 MVCアプリケーション開発 第三回

Technology Note 開発者向けBLOG

Ext JS

Ext JS4 MVCアプリケーション開発 第三回

こんにちは、ゼノフィ浅野です。

はじめに

前回までで、イベントハンドラを設定し、コントローラーとビューを切り離しました。
今回は、このコントローラーとビューの部分を中心に見ていきたいと思います。

コントローラーからビューへのアクセス

2つのオブジェクト

アクセスの説明の前に、コントローラーオブジェクトとビューオブジェクトの名前を見てみましょう。

  • Xenophy.controller.Header
  • Xenophy.view.Header

Xenophy.controller.Headerがコントローラーオブジェクト、 Xenophy.view.Headerがビューオブジェクトとなります。
MVCの形式で作成する場合、このように名前空間によってコントローラーとビューを分ける必要があります。
当然ですが、この2つは全くの別物です。

また、ビューはコンポーネントです。 Ext JS3ではコンポーネントがビューでありコントローラーでしたので、コンポーネントからコントローラー部分だけが切り離された、と考えましょう。 Ext JS4でもExt JS3のように記述して動作させることは可能ですが、 MVCの形を意識してコンポーネントからコントローラー処理部分を切り離した記述をするように心がけましょう。

イベントハンドラでコンポーネント取得

前回までで、コントローラーでcontrolメソッドを使用し、コンポーネントクエリによってターゲットを指定し、また、イベントハンドラも定義しました。
次は、イベントハンドラ内で必要なコンポーネントを取得することを考えてみましょう。

ここでは、

  • 「ボタン1が押される」 → 「ナビゲーションパネルを閉じる・開く」のトグルボタンの作成
  • 「ボタン2が押される」 → 「ヘッダーを非表示にし、3秒後に再表示する」

の2つの処理を行ってみたいと思います。

最初に、Xenophy.controller.Headerにrefsを設定します。

・src/app/controller/Header.js
1
2
3
4
5
6
7
    refs: [{
        ref: 'header',
        selector: 'xenophy-header'
    }, {
        ref: 'navi',
        selector: 'xenophy-navi'
    }]

refsを設定することで、コントローラーには次のメソッドが自動的に生成されます。

  • getHeader
  • getNavi

この2つのメソッドは、ビューを参照するためのメソッドです。
これらのメソッドを使用することによって、コントローラーからビューへのアクセスが可能になります。
それでは、getHeaderとgetNaviを使用して、各ボタンのイベントハンドラを実装してみたいと思います。

・src/app/controller/Header.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
    me.control({
        'xenophy-header button[action=button1]': {
            toggle: function(btn, pressed) {
 
                // Naviパネルコンポーネントオブジェクト取得
                var navi = this.getNavi();
 
                if (pressed) {
                    navi.collapse();
                } else {
                    navi.expand();
                }
 
            }
        },
        'xenophy-header button[action=button2]': {
            click: function() {
 
                var header = this.getHeader();
 
                header.getEl().ghost('b', {
                    callback: function() {
                        header.hide();
                        Ext.Function.defer(function() {
                            header.show();
                        }, 3000);
                    }
                });
 
            }
        },
        'xenophy-header button[action=button3]': {
            click: function() {
                Ext.Msg.alert('ボタン3', 'クリックされました。');
            }
        }
    });

ボタン1に対して、toggleイベントのハンドラを設定しました。
ボタンのトグル機能を有効にするために、viewで指定したボタン1のコンフィグオプションに次の設定を追加します。

・src/app/view/Header.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        items: [{
            text: 'ボタン1',
            enableToggle: true,
            iconCls: 'x-icon-1',
            action: 'button1'
        }, {
            text: 'ボタン2',
            iconCls: 'x-icon-2',
            action: 'button2'
        }, {
            text: 'ボタン3',
            iconCls: 'x-icon-3',
            action: 'button3'
        }]

enableToggleはデフォルトでfalseになっていますので、これにtrueを指定することで、ボタンにトグル機能が追加されます。
また、ハンドラ側では閉じる/開くの処理を記述しましたが、view側では設定されていないため、このままでは正常に動作しません。
viewに対して、閉じる/開くが可能になるように、下記のようにNaviのコンフィグオプションのcollapsibleをtrueに設定します。

・src/app/view/Viewport.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    items: [{
         xtype: 'xenophy-header',
        height: 35,
        region: 'north'
    }, {
        xtype: 'xenophy-navi',
        region: 'west',
        split: true,
        collapsible: true,
        width: 240
    }, {
        xtype: 'xenophy-center',
        region: 'center'
    }]

viewsについて

ここまではXenophy.view.ViewportのusesでHeader, Navi, Centerを読み込むように指定していましたが、Xenophy.controller.Mainのviewsに対して次のように指定することで、usesに指定しなくても読み込むことが可能です。

・src/app/controller/Main.js
1
2
3
4
5
6
7
8
9
10
11
Ext.define('Xenophy.controller.Main', {
 
    extend: 'Ext.app.Controller',
 
    views: ['Header', 'Navi', 'Center'],
 
    init: function() {
 
    }
 
});

usesやrequiresで指定しても、Ext.Loaderは実行されるため結果は同じですが、Mainコントローラーに定義することで、使用するビューをコントローラー側で明確にできる分、こちらの書き方の方がよいかもしれません。

異なる点として、viewsに指定した場合、自動的にクラス定義のオブジェクトを取得するために、 get[ビュー名]Viewというメソッドが生成されます。
上記のサンプルの場合では、getHeaderViewgetNaviViewgetCenterViewというメソッドが生成されます。

ここで、先ほどのrefsとviewsでは違う点があることに注意が必要です。
Headerのコントローラーに、refsを指定せずにviewsを指定すればよいと思われるかもしれません。
しかし、こちらで生成されるメソッドは「クラス定義のオブジェクト」を取得するメソッドであり、「インスタンス化されたコンポーネント」を取得するメソッドではありません。
ですので、コンポーネントのインスタンスにアクセスしたい場合は、refsで参照メソッドを作成しましょう。

今回までのソースサンプルはこちらです。

おわりに

第三回ではMVCアプリケーションのコントローラーからビューへのアクセス方法について説明しました。

ビューはコンポーネントであるため、refsを使用する以外にコンポーネントクエリを使用して取得することも可能です。
ですが、コンポーネントクエリはグローバル変数に何かを入れてアクセスしているようなものですので、可能な限りrefsを使用するべきでしょう。
次回は、Navi部分にツリーを使用して、model、storeを利用した処理を実装したいと思います。

PAGETOP