使用事件-Using Events
Ext JS的组件和类在其生命周期的各种阶段都可以触发大量的事件。事件允许代码对应用的变化做出响应,是 Ext JS中非常重要的概念。
什么是事件-What Are Events?
类在任何时候都可以对所关注的事情发生时触发事件。例如:当一个Ext.Component
渲染到屏幕时,Ext JS在渲染完成后触发一个事件。我们可以配置一个listeners
对象监听事件:
Ext.create('Ext.Panel', {
html: 'My Panel',
renderTo: Ext.getBody(),
listeners: {
afterrender: function() {
Ext.Msg.alert('Success!', 'We have been rendered');
}
}
});
在上述示例中,当 Panel 渲染到屏幕后,会有一个提示信息。类可以触发的所有事件都列在类的 API 页面 - 例如:Ext.panel.Panel
目前有 45 事件。
监听事件-Listening to Events
在一些场景下,Ext.Component
的afterrender
事件非常有用,你也会经常使用其他事件。例如:当 Ext.button.Button
被点击时触发 click
事件:
Ext.create('Ext.Button', {
text: 'Click Me',
renderTo: Ext.getBody(),
listeners: {
click: function() {
Ext.Msg.alert('Success!', 'I was clicked!');
}
}
});
组件可以根据需要监听许多事件。在下述的示例中,我们在mouseover
事件监听中调用了this.hide()
方法隐藏按钮,等待 1 秒后再显示该按钮。当调用 this.hide()
方法后,按钮被隐藏,接着触发了 hide
事件,调用 hide
事件监听,该监听程序在等待 1 秒后再次显示按钮:
Ext.create('Ext.Button', {
renderTo: Ext.getBody(),
text: 'My Button',
listeners: {
mouseover: function() {
this.hide();
},
hide: function() {
// Waits 1 second (1000ms), then shows the button again
Ext.defer(function() {
this.show();
}, 1000, this);
}
}
});
每当事件被触发后,都会调用对应的事件监听程序,所以你可以继续隐藏和显示按钮。
延后添加监听-Adding Listeners Later
在上述示例中,当类实例化后我们就为组件添加了事件监听。对于已经存在的实例,可以通过 on
方法为其添加事件监听:
var button = Ext.create('Ext.Button', {
renderTo: Ext.getBody(),
text: 'My Button'
});
button.on('click', function() {
Ext.Msg.alert('Success!', 'Event listener attached by .on');
});
使用 on
方法可以添加多个事件监听,类似与监听配置。下述示例实现了之前示例中按钮的隐藏和显示:
var button = Ext.create('Ext.Button', {
renderTo: Ext.getBody(),
text: 'My Button'
});
button.on({
mouseover: function() {
this.hide();
},
hide: function() {
Ext.defer(function() {
this.show();
}, 1000, this);
}
});
移除事件监听-Removing Listeners
就像随时可以添加事件监听一样,也可以随时移除事件监听。移除事件监听使用 un
方法。如果要移除事件监听,我们需要引用事件监听的方法。在上述示例中我们直接传递了事件监听方法。这次我们先定义事件监听处理程序并链接到一个变量 doSomething
。由于我们初始设置了事件监听,所以代码的运行跟之前一样。但是我们使用了延时处理方法,3秒后移除了事件监听。所以在3秒前点击按钮会有提示信息,3秒后点击按钮就没有任何反应了:
var doSomething = function() {
Ext.Msg.alert('Success!', 'listener called');
};
var button = Ext.create('Ext.Button', {
renderTo: Ext.getBody(),
text: 'My Button',
listeners: {
click: doSomething,
}
});
Ext.defer(function() {
button.un('click', doSomething);
}, 3000);
事件监听作用域-Scope Listener Option
作用域Scope
设置了事件监听处理程序内 this
的值。缺省情况下,this
是触发事件的类的实例。通常情况下是这样,但也并非总是这样。在之前的第二个示例中,我们调用 this.hide()
方法隐藏按钮,在下述示例中,我们创建一个 Button 和一个 Panel,为按钮添加一个 Panel 作用域的事件监听处理。要达到这个目的,我们需要传递一个包含事件监听处理和作用域的对象:
var panel = Ext.create('Ext.Panel', {
html: 'Panel HTML'
});
var button = Ext.create('Ext.Button', {
renderTo: Ext.getBody(),
text: 'Click Me'
});
button.on({
click: function() {
Ext.Msg.alert('Success!', this.getXType());
},
scope: panel
});
如果每个事件监听的作用域不同,也可以使用更明确的方式声明,或者你就不想简化这件事:
var panel = Ext.create('Ext.Panel', {
html: 'Panel HTML'
});
var button = Ext.create('Ext.Button', {
renderTo: Ext.getBody(),
text: 'Click Me'
});
button.on({
click: {
scope: panel,
fn: function() {
Ext.Msg.alert('Success!', this.getXType());
}
}
});
运行该示例将提示 Panel 的 xtype
信息。
只监听一次-Listening to an Event Once
或许你希望对某个事件只监听一次。该事件可能会被多次触发,但是我们只想处理一次。下述示例演示了这种情况:
var button = Ext.create('Ext.Button', {
renderTo: Ext.getBody(),
text: 'Click Me',
listeners: {
click: {
single: true,
fn: function() {
Ext.Msg.alert('Success!', 'I will say this only once');
}
}
}
});
使用缓冲配置-Using a Buffer Configuration
对于短时间内接连触发多次事件的场景,可以使用缓冲配置减少事件处理的次数。下述示例中,不论点击按钮多少次,监听处理程序每 2 秒内只调用一次:
var button = Ext.create('Ext.Button', {
renderTo: Ext.getBody(),
text: 'Click Me',
listeners: {
click: {
buffer: 2000,
fn: function() {
Ext.Msg.alert('Success!', 'I say this only once every 2 seconds');
}
}
}
});
触发自定义事件-Firing Custom Events
通过 fireEvent
方法,传递事件名称,可以触发自定义的事件。下述示例触发 myEvent
事件,并且带两个参数:按钮组件和1-100间的随机数:
var button = Ext.create('Ext.Button', {
renderTo: Ext.getBody(),
text: "Just wait 2 seconds",
listeners: {
myEvent: function(button, points) {
Ext.Msg.alert('Success!', 'myEvent fired! You score ' + points + ' points');
}
}
});
Ext.defer(function() {
var number = Math.ceil(Math.random() * 100);
button.fireEvent('myEvent', button, number);
}, 2000);
监听DOM事件-Listening for DOM Events
Not every ExtJS component raises every event. However, by targeting the container's element, we can attach many native events to which the component can then listen. In this example, we target . Containers do not have a click event. Let's give it one!
不是所有的 Ext JS 组件都能触发所有事件。但是可以通过为元素添加原生的事件处理,使得组件可以监听事件。下述示例中, Ext.container.Container
本来没有 click
事件,我们为其添加一个:
var container = Ext.create('Ext.Container', {
renderTo: Ext.getBody(),
html: 'Click Me!',
listeners: {
click: function(){
Ext.Msg.alert('Success!', 'I have been clicked!')
}
}
});
container.getEl().on('click', function(){
this.fireEvent('click', container);
}, container);
如果没有第二段代码,容器的 click
事件不会触发。由于我们为其DOM元素添加了 click
事件处理,我们已经扩展了容器的事件处理能力。
事件标准化-Event Normalization
事件标准化是允许 Ext JS 5+ 的应用能够在触摸设备上运行的关键所在。事件标注化的过程是在内部自动实现的,将标准的鼠标事件转换为对应的触摸和指针事件。指针事件是针对屏幕坐标位置进行事件处理的 W3C 标准,不考虑使用哪种输入设备(鼠标、触摸屏、手写笔等)。如果你的应用监听了鼠标事件,框架会根据需要自动监听相似的触摸或指针事件。例如:如果应用尝试监听鼠标按下(mousedown
)的事件:
myElement.on('mousedown', someFunction);
如果设备支持触摸事件,事件系统会将其转换为 touchstart
事件:
myElement.on('touchstart', someFunction);
如果设备支持指针事件,事件系统会将其转换为 pointerdown
事件:
myElement.on('pointerdown', someFunction);
自动转换事件处理可以让你的应用无需额外的编码就能够支持不同的设备。可以通过事件监听的选项禁用这种转换:
myElement.on({
mousedown: someFunction,
// only listen to mousedown.
// Do not call the handler in response to touchstart or pointerdown.
translate: false
});
更多事件-More Events
除了DOM事件和组件事件,Ext JS还能够识别诸如pinch
、rotate
、drag
等手势,参加《手势指南》。