Sencha Touchでイベントを設定する方法



[Sencha Advent Calendar 2012](http://www.adventar.org/calendars/23)の9日目担当の神代です。

sencha touchを使い始めのころコンポーネントに対して、、

* 初期化時
* タップされた時
* スワイプされた時

等々、イベントを設定する方法がいくつもあって若干戸惑った経験があったので、メモとして残しておきます

調べたところ、イベントを設定する方法は下記4つがよく使う方法です

* コントローラーのcontrolプロパティ
* コンポーネントのListenersプロパティ
* ボタンのhandlerプロパティ
* onメソッド

それぞれについて詳しく見ていきます

## コントローラー内のcontrolプロパティ

[APIドキュメント](http://docs.sencha.com/touch/2-0/#!/api/Ext.app.Controller-cfg-control)



### ComponentQuery指定

[ComponentQuery](http://docs.sencha.com/touch/2-0/#!/api/Ext.ComponentQuery)で指定した要素に対してイベント名とメソッドを設定することができます

```javascript
control: {
    'main-panel #logout-btn': {
        tap: 'doLogout'
    }
}

```

**main-panel #logout-btn**の部分がCompoinentQueryと言われる部分で[ComponentQuery](http://docs.sencha.com/touch/2-0/#!/api/Ext.ComponentQuery)のAPIドキュメントに指定方法が書いてあります。ここの指定でイベント付与するコンポーネントを特定しています。

* xtypeの指定：xtypeそのままか.（ドット）をつけて指定
* itemIdの指定：#（シャープ）をつけて指定

上記登録ではxtype、**main-panel**内のitemIdが**logout-btn**に対して、**tap**イベント発火時に**doLogout**が実行されるように登録しています

### refsプロパティとの併用

コントローラーには、コンポーネントの参照を予め設定して、取得しやすいようにするrefsプロパティがあります

例えば、あるコンポーネント（xtypeがmain-panel）にあるボタン(itemIdがlogout-btn)の参照を設定したい場合、

```javascript
refs: {
    logoutBtn: 'main-panel #logout-btn'
}
```

と指定しておくと、コントローラー内で下記のようなgetterで取得できるようになります（この場合のthisはコントローラー）

```javascript
var logoutBtn = this.getLogoutBtn();
```

前置きが長くなりましたが、上記のようにrefsに指定しておいたlogoutBtnに対してcontrolプロパティでイベント登録することもできます

ComponentQueryで指定したtapイベントをrefsの参照との併用に書き換えると以下のようになります

```javascript
refs: {
    logoutBtn: 'main-panel #logout-btn'
},
control: {
    'logoutBtn': {
        tap: 'doLogout'
    }
}
```

上記のようにすることで、logoutBtnのComponentQueryの記述は1回で済み、コードのメンテナンス性が上がります

## コンポーネントのListenersプロパティ

[APIドキュメント](http://docs.sencha.com/touch/2-0/#!/api/Ext.Component-cfg-listeners)

コンポーネントのListenersプロパティを利用するとコントローラーを使わなくても、コンポーネント内でイベントの登録ができます

```javascript:MainPanel.js
Ext.define('Sample.view.MainPanel',{
    extend: 'Ext.Panel'
    config: {
        ・
        ・
        ・
        listeners: {
            tap: 'doLogout'
        }
    },
    doLogout: function(){
        // logout処理
    }
}
```

上記の場合、listenersプロパティを利用して**tap**イベント発火時に**doLogout**が呼ばれるように登録されています

## ボタンのhandlerプロパティ

[APIドキュメント](http://docs.sencha.com/touch/2-0/#!/api/Ext.Button-cfg-handler)

ボタンコンポーネントの場合、特別にtap時の処理を登録するプロパティが用意されています。それがhandlerプロパティです

```javascript:MainPanel.js
Ext.define('Sample.view.MainPanel',{
    extend: 'Ext.Panel'
    config: {
        ・
        ・
        ・
        items: [
            {
                xtype: 'button',
                handler: function(){
                    var me = this,
                        parent = me.getParent();

                    parent.doLogout();
                }
            }
        ]
    },
    doLogout: function(){
        // logout処理
    }
}
```

上記のようにbuttonのhandlerプロパティに処理を記載しておくとボタンの**tap**イベント発火時に処理が実行されるようになります

## onメソッド

[APIドキュメント](http://docs.sencha.com/touch/2-0/#!/api/Ext.Component-method-on)

コンポーネントにはイベントを登録するonメソッドが用意されています。こちらを利用するとで動的なイベントの登録ができるようになります

例えば、xtype、**main-panel**内のitemIdが**logout-btn**に対して、**tap**イベント発火時に**doLogout**が実行されるように登録する場合は、

```javascript
var me = this,
    button = me.down('#logout-btn');

button.on('tap', me.doLogout);

```

（この場合のthisはmain-panelとする）

### 登録
onメソッドには発火タイミングによって3種類のメソッドが用意されています

* on：指定したイベントが発火時に実行される
* onBefore：onが実行される前に実行される
* onAfter：onが実行された後に実行される

### 削除
イベントの削除は[un](http://docs.sencha.com/touch/2-0/#!/api/Ext.Component-method-un)メソッドが用意されています
また、登録と同様に発火タイミング別に、un、unBefore、unAfterが各種用意されています

## [補足]イベントの調べ方

どのコンポーネントにどのようなイベントが存在するか調べる場合は、
APIドキュメントで該当コンポーネントのページを表示し上部メニューのEvents部分をみるとわかります

![スクリーンショット](https://pbs.twimg.com/media/A9k2KOwCMAATEea.png:large)