J'ai récemment commencé à apprendre ExtJS et j'ai du mal à comprendre comment gérer les événements. Je n'ai aucune expérience des versions précédentes d'ExtJS.
En lisant divers manuels, guides et pages de documentation, j'ai compris comment l'utiliser, mais je ne comprends pas très bien comment cela fonctionne. J'ai trouvé plusieurs tutoriels pour les anciennes versions d'ExtJS, mais je ne suis pas certain de leur applicabilité dans ExtJS 4.
Je cherche spécifiquement sur le "dernier mot" sur des choses comme
Par exemple, cette question m'amène à penser qu'un gestionnaire d'événements peut recevoir pas mal d'arguments. J'ai vu d'autres tutoriels où il n'y a que deux arguments pour le gestionnaire. Quels changements?
Commençons par décrire la gestion des événements des éléments DOM.
Tout d'abord, vous ne voudriez pas travailler directement avec le nœud DOM. Au lieu de cela, vous voudrez probablement utiliser l'interface Ext.Element
. Dans le but d’affecter des gestionnaires d’événements, Element.addListener
et Element.on
(ils sont équivalents) ont été créés. Donc, par exemple, si nous avons du HTML:
<div id="test_node"></div>
et nous voulons ajouter click
gestionnaire d'événements.
Récupérons Element
:
var el = Ext.get('test_node');
Vérifions maintenant la documentation pour l'événement click
. Son gestionnaire peut avoir trois paramètres:
click (Ext.EventObject e, HTMLElement t, Object eOpts)
Connaissant tout cela, nous pouvons affecter un gestionnaire:
// event name event handler
el.on( 'click' , function(e, t, eOpts){
// handling event here
});
La gestion des événements par les widgets est assez similaire à la gestion des événements par les nœuds DOM.
Tout d'abord, la gestion des événements de widgets est réalisée en utilisant Ext.util.Observable
mixin. Pour gérer correctement les événements, votre widget doit contenir Ext.util.Observable
Sous forme de mix. Tous les widgets intégrés (tels que Panneau, Formulaire, Arbre, Grille, ...) ont par défaut Ext.util.Observable
.
Pour les widgets, il existe deux manières d'affecter des gestionnaires. La première consiste à utiliser la méthode on (ou addListener
). Créons par exemple le widget Button
et lui affectons l'événement click
. Tout d'abord, vous devriez vérifier la documentation de l'événement pour les arguments du gestionnaire:
cliquez sur (Ext.button.Button this, Event e, Object eOpts)
Maintenant, utilisons 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 deuxième méthode consiste à utiliser le widget listeners config:
var myButton = Ext.create('Ext.button.Button', {
text: 'Test button',
listeners : {
click: function(btn, e, eOpts) {
// event handling here
console.log(btn, e, eOpts);
}
}
});
Notez que le widget Button
est un type spécial de widgets. L'événement de clic peut être assigné à ce widget en utilisant handler
config:
var myButton = Ext.create('Ext.button.Button', {
text: 'Test button',
handler : function(btn, e, eOpts) {
// event handling here
console.log(btn, e, eOpts);
}
});
Tout d’abord, vous devez enregistrer un événement en utilisant la méthode addEvents :
myButton.addEvents('myspecialevent1', 'myspecialevent2', 'myspecialevent3', /* ... */);
L'utilisation de la méthode addEvents
est facultative. Comme les commentaires à cette méthode indiquent qu'il n'est pas nécessaire d'utiliser cette méthode, elle fournit un emplacement pour la documentation des événements.
Pour déclencher votre événement, utilisez la méthode fireEvent :
myButton.fireEvent('myspecialevent1', arg1, arg2, arg3, /* ... */);
arg1, arg2, arg3, /* ... */
Sera passé dans le gestionnaire. Maintenant, nous pouvons gérer votre événement:
myButton.on('myspecialevent1', function(arg1, arg2, arg3, /* ... */) {
// event handling here
console.log(arg1, arg2, arg3, /* ... */);
});
Il est à noter que le meilleur endroit pour insérer addEvents l'appel de méthode est la méthode initComponent
du widget lorsque vous définissez un nouveau 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 */ });
Pour empêcher la formation de bulles, vous pouvez return false
Ou utiliser Ext.EventObject.preventDefault()
. Pour éviter l'action par défaut du navigateur, utilisez Ext.EventObject.stopPropagation()
.
Par exemple, assignons le gestionnaire d’événements clic à notre bouton. Et si ce n'est pas parti, le bouton a été cliqué pour empêcher l'action du navigateur par défaut
myButton.on('click', function(btn, e){
if (e.button !== 0)
e.preventDefault();
});
En plus de la très bonne réponse ci-dessus, je souhaite mentionner les événements à l'échelle de l'application qui peuvent être très utiles dans une configuration MVC pour permettre la communication entre les contrôleurs. (extjs4.1)
Disons que nous avons une station de contrôle (exemples Sencha MVC) avec une boîte de sélection:
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]);
},
...
});
Lorsque la zone de sélection déclenche un événement de modification, la fonction onStationSelect
est déclenchée.
Dans cette fonction, nous voyons:
this.application.fireEvent('stationstart', selection[0]);
Cela crée et déclenche un événement à l'échelle de l'application que nous pouvons écouter à partir de tout autre contrôleur.
Ainsi, dans un autre contrôleur, nous pouvons maintenant savoir quand la boîte de sélection de station a été modifiée. Cela se fait en écoutant this.application.on
Comme suit:
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 la selectbox a été modifiée, nous activons maintenant la fonction onStationStart
dans le contrôleur Song
également ...
D'après la documentation Sencha:
Les événements d'application sont extrêmement utiles pour les événements comportant de nombreux contrôleurs. Au lieu d'écouter le même événement d'affichage dans chacun de ces contrôleurs, un seul contrôleur écoute l'événement d'affichage et déclenche un événement à l'échelle de l'application que les autres peuvent écouter. Cela permet également aux contrôleurs de communiquer les uns avec les autres sans se rendre compte de l’existence de chacun ou dépendre de celle-ci.
Dans mon cas: cliquer sur un nœud d’arbre pour mettre à jour les données dans un panneau de grille.
Mise à jour 2016 grâce à @ gm2008 à partir des commentaires ci-dessous:
En termes de déclenchement d'événements personnalisés à l'échelle de l'application, il existe une nouvelle méthode maintenant après la publication de ExtJS V5.1 , qui utilise Ext.GlobalEvents
.
Lorsque vous déclenchez des événements, vous pouvez appeler: Ext.GlobalEvents.fireEvent('custom_event');
Lorsque vous enregistrez un gestionnaire de l'événement, vous appelez: Ext.GlobalEvents.on('custom_event', function(arguments){/* handler codes*/}, scope);
Cette méthode n'est pas limitée aux contrôleurs. Tout composant peut gérer un événement personnalisé en plaçant l'objet composant en tant que portée du paramètre d'entrée.
Une astuce supplémentaire pour les auditeurs d'événements du contrôleur.
Vous pouvez utiliser des caractères génériques pour surveiller un événement à partir de n'importe quel composant:
this.control({
'*':{
myCustomEvent: this.doSomething
}
});
Je voulais juste ajouter quelques sous aux excellentes réponses ci-dessus: Si vous travaillez sur des versions antérieures à Extjs 4.1 et que vous n'avez pas d'événements à l'échelle de l'application mais que vous en avez besoin, j'ai utilisé une technique très simple qui pourrait vous aider: Créer une objet simple étendant Observable et définissez tous les événements d’application dont vous pourriez avoir besoin. Vous pouvez ensuite déclencher ces événements à partir de n’importe où dans votre application, y compris d’un élément html dom réel, et les écouter depuis n’importe quel composant en relayant les éléments requis à partir de ce composant.
Ext.define('Lib.MessageBus', {
extend: 'Ext.util.Observable',
constructor: function() {
this.addEvents(
/*
* describe the event
*/
"eventname"
);
this.callParent(arguments);
}
});
Ensuite, vous pouvez, à partir de tout autre composant:
this.relayEvents(MesageBus, ['event1', 'event2'])
Et tirez-les depuis n'importe quel composant ou élément dom:
MessageBus.fireEvent('event1', somearg);
<input type="button onclick="MessageBus.fireEvent('event2', 'somearg')">
Juste deux autres choses que j'ai trouvé utiles de savoir, même si elles ne font pas partie de la question, vraiment.
Vous pouvez utiliser la méthode relayEvents
pour demander à un composant d'écouter certains événements d'un autre composant, puis de les réexécuter comme s'ils provenaient du premier composant. Les documents de l'API donnent l'exemple d'une grille relayant l'événement store load
. C'est très pratique lorsque vous écrivez des composants personnalisés qui encapsulent plusieurs sous-composants.
Inversement, c’est-à-dire transmettre les événements reçus par un composant encapsulant mycmp
à l’un de ses sous-composants subcmp
, peut être fait comme ceci
mycmp.on('show' function (mycmp, eOpts)
{
mycmp.subcmp.fireEvent('show', mycmp.subcmp, eOpts);
});