我在今年的 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 元素侦听相同事件时,使用“委托”事件选项并将侦听器附加到它们的公共父级而不是单个元素。这表现得更好,让您可以任意创建/销毁子元素,而不必担心不断地将事件侦听器附加/删除到每个子元素。避免使用类似的东西
.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');
}
});