javascript - examples - sencha html
Explicar el manejo de eventos ExtJS 4 (5)
Disparando eventos amplios de la aplicación
Cómo hacer que los controladores hablen entre ellos ...
Además de la gran respuesta anterior, quiero mencionar los eventos de toda la aplicación que pueden ser muy útiles en una configuración de MVC para habilitar la comunicación entre los controladores. (extjs4.1)
Digamos que tenemos un controlador Station (ejemplos Sencha MVC) con un cuadro de selección:
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]);
},
...
});
Cuando la casilla de selección activa un evento de cambio, se dispara la función onStationSelect
.
Dentro de esa función vemos:
this.application.fireEvent(''stationstart'', selection[0]);
Esto crea y dispara un evento de toda la aplicación que podemos escuchar desde cualquier otro controlador.
Por lo tanto, en otro controlador ahora podemos saber cuándo se ha cambiado el cuadro de selección de la estación. Esto se hace escuchando this.application.on
siguiente manera:
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?'');
},
}
Si se ha cambiado la onStationStart
de onStationStart
, ahora onStationStart
la función onStationStart
en la Song
del controlador también ...
De los documentos de Sencha:
Los eventos de aplicación son extremadamente útiles para eventos que tienen muchos controladores. En lugar de escuchar el mismo evento de visualización en cada uno de estos controladores, solo un controlador escucha el evento de visualización y dispara un evento de toda la aplicación que los demás pueden escuchar. Esto también permite que los controladores se comuniquen entre sí sin conocer o depender de la existencia de los demás.
En mi caso: hacer clic en un nodo de árbol para actualizar los datos en un panel de cuadrícula.
Actualización 2016 gracias a @ gm2008 de los comentarios a continuación:
En términos de activación de eventos personalizados para toda la aplicación, ahora existe un nuevo método después de la publicación de ExtJS V5.1 , que usa Ext.GlobalEvents
.
Cuando Ext.GlobalEvents.fireEvent(''custom_event'');
eventos, puede llamar a: Ext.GlobalEvents.fireEvent(''custom_event'');
Cuando registra un manejador del evento, llama: Ext.GlobalEvents.on(''custom_event'', function(arguments){/* handler codes*/}, scope);
Este método no está limitado a los controladores. Cualquier componente puede manejar un evento personalizado mediante la colocación del objeto componente como el alcance del parámetro de entrada.
Recientemente comencé a aprender ExtJS y tengo problemas para entender cómo manejar eventos. No tengo experiencia con versiones anteriores de ExtJS.
Después de leer varios manuales, guías y páginas de documentación, he descubierto cómo usarlo, pero no tengo claro cómo funciona. He encontrado varios tutoriales para versiones anteriores de ExtJS, pero no estoy seguro de qué tan aplicables son en ExtJS 4.
Estoy buscando específicamente la "última palabra" sobre cosas como
- ¿Qué argumentos pasa una función de manejo de eventos? ¿Hay un conjunto estándar de argumentos que siempre pasan?
- cómo definir eventos personalizados para los componentes personalizados que escribimos? ¿Cómo podemos disparar estos eventos personalizados?
- ¿El valor de retorno (verdadero / falso) afecta cómo burbujea el evento? Si no, ¿cómo podemos controlar el burbujeo del evento desde dentro o fuera del controlador de eventos?
- ¿Hay una forma estándar de registrar oyentes de eventos? (He encontrado dos formas diferentes hasta ahora, y no estoy seguro de por qué se usó cada método).
Por ejemplo, esta pregunta me lleva a creer que un controlador de eventos puede recibir bastantes argumentos. He visto otros tutoriales donde solo hay dos argumentos para el controlador. ¿Que cambios?
Comencemos describiendo el manejo de eventos de los elementos DOM.
Manejo de eventos del nodo DOM
Antes que nada, no querrás trabajar directamente con el nodo DOM. En su lugar, probablemente desee utilizar la interfaz Ext.Element
. Con el propósito de asignar manejadores de eventos, se Element.addListener
y Element.on
(estos son equivalentes). Entonces, por ejemplo, si tenemos html:
<div id="test_node"></div>
y queremos agregar controlador de evento de click
.
Recuperemos Element
:
var el = Ext.get(''test_node'');
Ahora revisemos los documentos para el evento click
. Su controlador puede tener tres parámetros:
haga clic en (Ext.EventObject e, HTMLElement t, Object eOpts)
Sabiendo todo esto podemos asignar controlador:
// event name event handler
el.on( ''click'' , function(e, t, eOpts){
// handling event here
});
Manejo de eventos de widgets
El manejo de eventos de widgets es bastante similar al manejo de eventos de nodos DOM.
En primer lugar, el manejo de eventos de widgets se realiza utilizando Ext.util.Observable
mixin. Para gestionar adecuadamente los eventos, su widget debe contener Ext.util.Observable
como mixin. Todos los widgets integrados (como Panel, Formulario, Árbol, Cuadrícula, ...) tienen Ext.util.Observable
como mixin por defecto.
Para los widgets hay dos formas de asignar manejadores. El primero es usar on método (o addListener
). Vamos a crear, por ejemplo, el widget Button
y asignarle un evento de click
. En primer lugar, debe verificar los documentos del evento para los argumentos del controlador:
haga clic en (Ext.button.Button this, Evento e, Objeto eOpts)
Ahora vamos a usar 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);
});
La segunda forma es usar la configuración de listeners del widget:
var myButton = Ext.create(''Ext.button.Button'', {
text: ''Test button'',
listeners : {
click: function(btn, e, eOpts) {
// event handling here
console.log(btn, e, eOpts);
}
}
});
Tenga en cuenta que el widget de Button
es un tipo especial de widgets. El evento Click se puede asignar a este widget utilizando la configuración del handler
:
var myButton = Ext.create(''Ext.button.Button'', {
text: ''Test button'',
handler : function(btn, e, eOpts) {
// event handling here
console.log(btn, e, eOpts);
}
});
Eventos personalizados disparando
Antes que nada, necesitas registrar un evento usando el método addEvents :
myButton.addEvents(''myspecialevent1'', ''myspecialevent2'', ''myspecialevent3'', /* ... */);
Usar el método addEvents
es opcional. Como los comentarios a este método dicen que no es necesario usar este método, pero proporciona lugar para la documentación de eventos.
Para fireEvent su evento utilice el método fireEvent :
myButton.fireEvent(''myspecialevent1'', arg1, arg2, arg3, /* ... */);
arg1, arg2, arg3, /* ... */
pasará al controlador. Ahora podemos manejar su evento:
myButton.on(''myspecialevent1'', function(arg1, arg2, arg3, /* ... */) {
// event handling here
console.log(arg1, arg2, arg3, /* ... */);
});
Vale la pena mencionar que el mejor lugar para insertar la llamada al método addEvents es el método initComponent
del widget cuando se está definiendo un nuevo widget:
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 */ });
Previniendo el burbujeo del evento
Para evitar el burbujeo, puede return false
o usar Ext.EventObject.preventDefault()
. Para evitar la acción predeterminada del navegador, use Ext.EventObject.stopPropagation()
.
Por ejemplo, asignemos el controlador de eventos click a nuestro botón. Y si no se hizo clic en el botón izquierdo, se evita la acción predeterminada del navegador:
myButton.on(''click'', function(btn, e){
if (e.button !== 0)
e.preventDefault();
});
Sólo dos cosas más que encontré útiles para saber, incluso si no son parte de la pregunta, realmente.
Puede utilizar el método relayEvents
para indicar a un componente que escuche ciertos eventos de otro componente y luego volver a dispararlos como si se originaran desde el primer componente. Los documentos API dan el ejemplo de una red que retransmite el evento de load
la tienda. Es bastante útil cuando se escriben componentes personalizados que encapsulan varios subcomponentes.
A la inversa, es decir, transmitir eventos recibidos por un componente de encapsulado mycmp
a uno de sus subcomponentes subcmp
, se puede hacer así
mycmp.on(''show'' function (mycmp, eOpts)
{
mycmp.subcmp.fireEvent(''show'', mycmp.subcmp, eOpts);
});
Solo quería agregar un par de peniques a las excelentes respuestas anteriores: si está trabajando en pre Extjs 4.1 y no tiene eventos en toda la aplicación pero los necesita, he estado usando una técnica muy simple que podría ayudar: crear un Objeto simple que amplía Observable y define los eventos amplios de la aplicación que pueda necesitar. A continuación, puede activar esos eventos desde cualquier lugar de la aplicación, incluido el elemento dom html real y escucharlos desde cualquier componente mediante la retransmisión de los elementos requeridos desde ese componente.
Ext.define(''Lib.MessageBus'', {
extend: ''Ext.util.Observable'',
constructor: function() {
this.addEvents(
/*
* describe the event
*/
"eventname"
);
this.callParent(arguments);
}
});
Entonces puedes, desde cualquier otro componente:
this.relayEvents(MesageBus, [''event1'', ''event2''])
Y despídalos de cualquier componente o elemento dom:
MessageBus.fireEvent(''event1'', somearg);
<input type="button onclick="MessageBus.fireEvent(''event2'', ''somearg'')">
Un truco más para los oyentes de eventos de controlador.
Puede usar comodines para ver un evento desde cualquier componente:
this.control({
''*'':{
myCustomEvent: this.doSomething
}
});