解释ExtJS 4事件处理
我最近开始学习ExtJS,并且无法理解如何处理事件。 我没有任何以前版本的ExtJS的经验。
从阅读各种手册,指南和文档页面,我已经想出了如何使用它,但我不清楚它的工作原理。 我发现了几个旧版ExtJS的教程,但我不确定它们在ExtJS 4中的适用性。
我特别关注诸如此类的“最终词”
例如,这个问题让我相信一个事件处理程序可以接收到很多的参数。 我见过其他教程,其中只有两个参数的处理程序。 什么改变?
我们从描述DOM元素的事件处理开始。
DOM节点事件处理
  首先你不想直接使用DOM节点。  相反,你可能会想要利用Ext.Element接口。  为了分配事件处理程序,创建了Element.addListener和Element.on (这些是等同的)。  所以,例如,如果我们有html: 
<div id="test_node"></div>
  我们希望添加click事件处理程序。 
  让我们检索Element : 
var el = Ext.get('test_node');
  现在让我们来检查click事件的文档。  它的处理程序可能有三个参数: 
单击(Ext.EventObject e,HTMLElement t,Object eOpts)
知道所有这些东西,我们可以分配处理程序:
//       event name      event handler
el.on(    'click'        , function(e, t, eOpts){
  // handling event here
});
小部件事件处理
小部件事件处理与DOM节点事件处理非常相似。
  首先,小部件事件处理是通过利用Ext.util.Observable mixin来实现的。  为了正确处理事件,你的小部件必须将Ext.util.Observable作为一个mixin来处理。  所有内置小部件(如面板,窗体,树,网格等)都将Ext.util.Observable默认为mixin。 
  对于小部件,有两种分配处理程序的方法。  第一个 - 是使用方法(或addListener )。  例如,我们创建Button小部件并为其分配click事件。  首先你应该检查处理程序参数的事件文档: 
点击(Ext.button.Button this,Event e,Object eOpts)
  现在让我们使用on : 
var myButton = Ext.create('Ext.button.Button', {
  text: 'Test button'
});
myButton.on('click', function(btn, e, eOpts) {
  // event handling here
  console.log(btn, e, eOpts);
});
第二种方法是使用小部件的监听器配置:
var myButton = Ext.create('Ext.button.Button', {
  text: 'Test button',
  listeners : {
    click: function(btn, e, eOpts) {
      // event handling here
      console.log(btn, e, eOpts);
    }
  }
});
  注意Button小部件是一种特殊的小部件。  点击事件可以通过使用handler配置分配给这个小部件: 
var myButton = Ext.create('Ext.button.Button', {
  text: 'Test button',
  handler : function(btn, e, eOpts) {
    // event handling here
    console.log(btn, e, eOpts);
  }
});
自定义事件触发
首先你需要使用addEvents方法注册一个事件:
myButton.addEvents('myspecialevent1', 'myspecialevent2', 'myspecialevent3', /* ... */);
  使用addEvents方法是可选的。  作为这种方法的评论说,没有必要使用这种方法,但它提供了事件文档的地方。 
使用fireEvent方法来触发您的事件:
myButton.fireEvent('myspecialevent1', arg1, arg2, arg3, /* ... */);
  arg1, arg2, arg3, /* ... */将被传入处理函数。  现在我们可以处理您的活动: 
myButton.on('myspecialevent1', function(arg1, arg2, arg3, /* ... */) {
  // event handling here
  console.log(arg1, arg2, arg3, /* ... */);
});
  值得一提的是,当您定义新窗口小部件时,插入addEvents方法调用的最佳位置是窗口小部件的initComponent方法: 
Ext.define('MyCustomButton', {
  extend: 'Ext.button.Button',
  // ... other configs,
  initComponent: function(){
    this.addEvents('myspecialevent1', 'myspecialevent2', 'myspecialevent3', /* ... */);
    // ...
    this.callParent(arguments);
  }
});
var myButton = Ext.create('MyCustomButton', { /* configs */ });
防止事件冒泡
  为了防止冒泡,您可以return false或使用Ext.EventObject.preventDefault() 。  为了防止浏览器的默认操作使用Ext.EventObject.stopPropagation() 。 
例如,让我们将点击事件处理程序分配给我们的按钮。 如果没有点击左键,则防止默认的浏览器操作:
myButton.on('click', function(btn, e){
  if (e.button !== 0)
    e.preventDefault();
});
发射应用程序广泛的事件
如何让控制器相互交谈...
除了上面非常好的答案之外,我想提及应用程序范围内的事件,这些事件在MVC设置中可以非常有用,以实现控制器之间的通信。 (extjs4.1)
假设我们有一个控制器站(Sencha MVC示例)和一个选择框:
Ext.define('Pandora.controller.Station', {
    extend: 'Ext.app.Controller',
    ...
    init: function() {
        this.control({
            'stationslist': {
                selectionchange: this.onStationSelect
            },
            ...
        });
    },
    ...
    onStationSelect: function(selModel, selection) {
        this.application.fireEvent('stationstart', selection[0]);
    },    
   ...
});
  当选择框触发更改事件时,将onStationSelect功能。 
在这个函数中我们看到:
this.application.fireEvent('stationstart', selection[0]);
这会创建并触发我们可以从任何其他控制器收听的应用程序范围事件。
  因此,在另一个控制器中,我们现在可以知道何时站选择框已被更改。  这是通过听this.application.on ,如下所示: 
Ext.define('Pandora.controller.Song', {
    extend: 'Ext.app.Controller', 
    ...
    init: function() {
        this.control({
            'recentlyplayedscroller': {
                selectionchange: this.onSongSelect
            }
        });
        // Listen for an application wide event
        this.application.on({
            stationstart: this.onStationStart, 
                scope: this
        });
    },
    ....
    onStationStart: function(station) {
        console.info('I called to inform you that the Station controller select box just has been changed');
        console.info('Now what do you want to do next?');
    },
}
  如果选择框已被更改,我们现在在控制器Song onStationStart上的功能也... 
来自Sencha文档:
应用程序事件对于具有多个控制器的事件非常有用。 与其在每个控制器中侦听相同的视图事件,只有一个控制器侦听视图事件并触发其他人可以侦听的应用程序范围的事件。 这也允许管制员彼此沟通而不知道或依赖彼此的存在。
在我的情况下:点击树节点来更新网格面板中的数据。
感谢@ gm2008从以下评论更新2016年:
  在发布应用程序范围内的自定义事件方面,在ExtJS V5.1发布后,现在有一种新方法,它使用了Ext.GlobalEvents 。 
  当你触发事件时,你可以调用: Ext.GlobalEvents.fireEvent('custom_event'); 
  当你注册事件的处理程序时,你可以调用: Ext.GlobalEvents.on('custom_event', function(arguments){/* handler codes*/}, scope); 
这种方法不限于控制器。 任何组件都可以通过将组件对象作为输入参数范围来处理自定义事件。
在Sencha Docs中找到:MVC第2部分
控制器事件监听器的另一个技巧。
您可以使用通配符从任何组件监视事件:
this.control({
   '*':{ 
       myCustomEvent: this.doSomething
   }
});
上一篇: Explain ExtJS 4 event handling
下一篇: How to Cancel?
