今年の SenchaCon でこの質問をしたところ、Sencha の開発者は、DOM リスナーをビュー内にアタッチし、ビューがそれらをより意味のあるコンポーネント イベントに抽象化し、再起動することを意図していると述べました。
たとえば、人の顔のグリッドを表示する UserGallery というビューを作成しているとします。UserGallery ビュー クラス内で、<img>
タグの DOM クリック イベントをリッスンしてイベントとターゲットを受け取ります。ビューは「userselected」というコンポーネント イベントを起動し、DOM ターゲットの代わりにクリックされたユーザーのモデル インスタンスを渡します。 .
最終的な目標は、ビューだけがインターフェイス イベントや DOM 要素などに関与し、アプリケーション レベルのコントローラーが意味のあるユーザー インテントのみを処理するようにすることです。アプリケーションとコントローラーのコードは、マークアップ構造またはインターフェイスの実装にまったく結合しないでください。
サンプルビュー
Ext.define('MyApp.view.UserGallery', {
extend: 'Ext.Component'
,xtype: 'usergallery'
,tpl: '<tpl for="users"><img src="{avatar_src}" data-ID="{id}"></tpl>'
,initComponent: function() {
this.addEvents('userselected');
this.callParent(arguments);
}
,afterRender: function() {
this.mon(this.el, 'click', this.onUserClick, this, {delegate: 'img'});
this.callParent(arguments);
}
,onUserClick: function(ev, t) {
ev.stopEvent();
var userId = Ext.fly(t).getAttribute('data-ID');
this.fireEvent('userselected', this, userId, ev);
}
});
ビューに関する注意事項
- 管理されたものだけが必要な場合は「Ext.Component」を拡張します
<div>
.Ext.Panelは、タイトルバー、ツールバー、折りたたみなどをサポートするために非常に重いです.
- コンポーネントから DOM 要素にリスナーをアタッチする場合は、「マネージド」リスナーを使用します (Component.mon を参照)。コンポーネントによって管理されるリスナーは、そのコンポーネントが破棄されると自動的に解放されます
- 複数の DOM 要素から同じイベントをリッスンする場合は、"delegate" イベント オプションを使用して、個々の要素ではなく共通の親にリスナーをアタッチします。これによりパフォーマンスが向上し、イベントリスナーを各子に継続的にアタッチ/削除することを心配することなく、子要素を任意に作成/破棄できます。のようなものを使用しないでください
.select('img').on('click', handler)
- ビューからイベントを発生させる場合、Sencha の規則では、イベントへの最初のパラメーターは、イベント
scope
を発生させたビューへの参照です。これは、イベント ハンドラーの実際のスコープがコントローラーである必要があるコントローラーからイベントが処理されている場合に便利です。
サンプルコントローラー
Ext.define('app.controller.myController', {
extend: 'Ext.app.Controller'
,init: function() {
this.control({
'usergallery': {
userselected: function(galleryView, userId, ev) {
this.openUserProfile(userID);
}
}
});
}
,openUserProfile: function(userId) {
alert('load another view here');
}
});