Spiegare la gestione degli eventi ExtJS 4


130

Di recente ho iniziato a studiare ExtJS e ho difficoltà a capire come gestire gli eventi. Non ho esperienza con nessuna versione precedente di ExtJS.

Dalla lettura di vari manuali, guide e pagine di documentazione, ho capito come usarlo, ma non sono chiaro su come funzioni. Ho trovato diversi tutorial per le versioni precedenti di ExtJS, ma non sono sicuro di quanto siano applicabili in ExtJS 4.

In particolare sto cercando la "parola finale" su cose come

  • quali argomenti passa una funzione di gestione degli eventi? Esiste un insieme standard di argomenti che vengono sempre superati?
  • come definire eventi personalizzati per i componenti personalizzati che scriviamo? come possiamo sparare questi eventi personalizzati?
  • il valore restituito (vero / falso) influenza il modo in cui l'evento bolle? In caso contrario, come possiamo controllare il bubbling di eventi dall'interno o dall'esterno del gestore eventi?
  • esiste un modo standard per registrare i listener di eventi? (Mi sono imbattuto in due modi diversi fino ad ora, e non sono sicuro del motivo per cui ogni metodo è stato utilizzato).

Ad esempio, questa domanda mi porta a credere che un gestore di eventi possa ricevere parecchi argomenti. Ho visto altri tutorial in cui ci sono solo due argomenti per il gestore. Cosa cambia


2
Hai appena notato ... fuori tema?
jrharshath,

12
88 Voti sulla domanda, 155 voti sulla prima risposta e il grande e potente Andrew decide che questo è fuori tema. In corso un serio viaggio di potere!
Boatcoder

3
Ho votato per riaprire questa domanda poiché le risposte qui sono una miniera d'oro. Ho modificato la domanda per adattarla meglio allo stile Q e A.
Dal

1
Ti preghiamo di aprire di nuovo questa domanda perché è una domanda davvero utile e genuina. così ciecamente che non possiamo chiuderlo.
Piyush Dholariya,

2
Questa è una domanda ben formulata e non vedo alcun motivo per chiuderla. Richiamare questo argomento è ridicolo. Votato per riaprire.
Mike Fuchs,

Risposte:


222

Cominciamo descrivendo la gestione degli eventi degli elementi DOM.

Gestione degli eventi del nodo DOM

Prima di tutto non vorrai lavorare direttamente con il nodo DOM. Invece probabilmente vorrai utilizzare l' Ext.Elementinterfaccia. Ai fini dell'assegnazione dei gestori di eventi Element.addListenere Element.on(questi sono equivalenti) sono stati creati. Quindi, ad esempio, se abbiamo HTML:

<div id="test_node"></div>

e vogliamo aggiungere il clickgestore eventi.
Recuperiamo Element:

var el = Ext.get('test_node');

Ora controlliamo i documenti per l' clickevento. Il gestore può avere tre parametri:

fare clic su (Ext.EventObject e, HTMLElement t, Object eOpts)

Conoscendo tutto ciò che possiamo assegnare al gestore:

//       event name      event handler
el.on(    'click'        , function(e, t, eOpts){
  // handling event here
});

Gestione degli eventi dei widget

La gestione degli eventi dei widget è molto simile alla gestione degli eventi dei nodi DOM.

Innanzitutto, la gestione degli eventi dei widget viene realizzata utilizzando il Ext.util.Observablemixin. Per gestire correttamente gli eventi, il tuo widget deve essere considerato Ext.util.Observablecome un mixin. Tutti i widget integrati (come Pannello, Modulo, Albero, Griglia, ...) hanno Ext.util.Observablecome impostazione predefinita un mixin.

Per i widget ci sono due modi per assegnare i gestori. Il primo - è usare il metodo (o addListener). Creiamo ad esempio un Buttonwidget e assegniamo un clickevento ad esso. Prima di tutto dovresti controllare i documenti dell'evento per gli argomenti del gestore:

fare clic su (pulsante Ext.button, Event e, Object eOpts)

Ora usiamo 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);
});

Il secondo modo è usare la configurazione dei listener dei 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);
    }
  }
});

Si noti che il Buttonwidget è un tipo speciale di widget. L'evento Click può essere assegnato a questo widget usando handlerconfig:

var myButton = Ext.create('Ext.button.Button', {
  text: 'Test button',
  handler : function(btn, e, eOpts) {
    // event handling here
    console.log(btn, e, eOpts);
  }
});

Attivazione di eventi personalizzati

Prima di tutto devi registrare un evento usando il metodo addEvents :

myButton.addEvents('myspecialevent1', 'myspecialevent2', 'myspecialevent3', /* ... */);

L'uso del addEventsmetodo è facoltativo. Come dicono i commenti a questo metodo, non è necessario utilizzare questo metodo, ma fornisce spazio per la documentazione degli eventi.

Per generare il tuo evento usa il metodo fireEvent :

myButton.fireEvent('myspecialevent1', arg1, arg2, arg3, /* ... */);

arg1, arg2, arg3, /* ... */sarà passato al gestore. Ora possiamo gestire il tuo evento:

myButton.on('myspecialevent1', function(arg1, arg2, arg3, /* ... */) {
  // event handling here
  console.log(arg1, arg2, arg3, /* ... */);
});

Vale la pena ricordare che il posto migliore per inserire la chiamata al metodo addEvents è il initComponentmetodo del widget quando si definiscono nuovi 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 */ });

Prevenire il gorgoglio degli eventi

Per evitare il gorgoglio è possibile return falseo utilizzare Ext.EventObject.preventDefault(). Per impedire l'uso dell'azione predefinita del browser Ext.EventObject.stopPropagation().

Ad esempio, assegniamo il gestore dell'evento click al nostro pulsante. E se non si fa clic sul pulsante sinistro, impedire l'azione predefinita del browser:

myButton.on('click', function(btn, e){
  if (e.button !== 0)
    e.preventDefault();
});

3
questo è avidità, ma c'è un modo per fare la cosa "addEvents" tramite una configurazione? :)
jrharshath,

@jrharshath, per quanto ne so, sfortunatamente, non c'è modo di farlo tramite la configurazione.
Molecular Man

come si creano questi -myspecialevent1 ', vedo che l'hai allegato e gestito, ma come li creiamo?
Ehi, ora,

1
Risposta brillante! Sono nuovo di ExtJs e stavo cercando un modo per fare riferimento a qualsiasi elemento della pagina e utilizzare i gestori di eventi su di essi, proprio come jQuery. Mi hai insegnato a! Grazie!
Rutwick Gangurde,

1
piccolo errore nella sezione "Prevenzione del gorgogliamento di eventi". stopPropagation viene utilizzato per impedire il bubling degli eventi e preventDefault viene utilizzato per impedire il comportamento / l'azione predefiniti.
MatRt

44

Attivazione di eventi di ampia portata

Come far parlare l'un l'altro i controller ...

Oltre all'ottima risposta di cui sopra, desidero menzionare gli eventi a livello di applicazione che possono essere molto utili in una configurazione MVC per consentire la comunicazione tra i controller. (Extjs4.1)

Diciamo che abbiamo una Controller Station (esempi Sencha MVC) con una casella di selezione:

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]);
    },    
   ...
});

Quando la casella di selezione attiva un evento di modifica, la funzione onStationSelectviene attivata.

All'interno di quella funzione vediamo:

this.application.fireEvent('stationstart', selection[0]);

Questo crea e genera un evento a livello di applicazione che possiamo ascoltare da qualsiasi altro controller.

Quindi in un altro controller ora possiamo sapere quando la casella di selezione della stazione è stata cambiata. Questo viene fatto ascoltando this.application.oncome segue:

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?');
    },
}

Se la casella di selezione è stata modificata, ora attiviamo anche la funzione onStationStartnel controller Song...

Dai documenti di Sencha:

Gli eventi dell'applicazione sono estremamente utili per eventi con molti controller. Invece di ascoltare lo stesso evento di visualizzazione in ciascuno di questi controller, solo un controller ascolta l'evento di visualizzazione e genera un evento a livello di applicazione che gli altri possono ascoltare. Ciò consente inoltre ai controller di comunicare tra loro senza conoscere o dipendere dall'esistenza reciproca.

Nel mio caso: fare clic su un nodo dell'albero per aggiornare i dati in un pannello della griglia.

Aggiornamento 2016 grazie a @ gm2008 dai commenti qui sotto:

In termini di attivazione di eventi personalizzati a livello di applicazione, esiste un nuovo metodo ora dopo la pubblicazione di ExtJS V5.1 , che sta utilizzando Ext.GlobalEvents.

Quando si attivano eventi, è possibile chiamare: Ext.GlobalEvents.fireEvent('custom_event');

Quando registri un gestore dell'evento, chiami: Ext.GlobalEvents.on('custom_event', function(arguments){/* handler codes*/}, scope);

Questo metodo non è limitato ai controller. Qualsiasi componente può gestire un evento personalizzato inserendo l'oggetto componente come ambito del parametro di input.

Trovato in Sencha Docs: MVC Parte 2


1
In termini di attivazione di eventi personalizzati a livello di applicazione, esiste un nuovo metodo ora dopo la pubblicazione di ExtJS V5.1, che utilizza Ext.GlobalEvents. Quando si attiva l'evento, si chiama Ext.GlobalEvents.fireEvent('custom_event');Quando si registra un gestore dell'evento, si chiama Ext.GlobalEvents.on('custom_event', function(arguments){/* handler codes*/}, scope};Here is a fiddle . Questo metodo non è limitato ai controller. Qualsiasi componente può gestire un evento personalizzato inserendo l'oggetto componente come parametro di input scope. La domanda dovrebbe essere riaperta.
gm2008,

15

Un altro trucco per i listener di eventi del controller.

È possibile utilizzare i caratteri jolly per guardare un evento da qualsiasi componente:

this.control({
   '*':{ 
       myCustomEvent: this.doSomething
   }
});

12

Volevo solo aggiungere un po 'di pence alle eccellenti risposte di cui sopra: se stai lavorando su pre Extjs 4.1 e non hai eventi a livello di applicazione ma ne hai bisogno, sto usando una tecnica molto semplice che potrebbe aiutare: Creare un semplice oggetto che estende Osservabile e definisce tutti gli eventi a livello di app di cui potresti aver bisogno in esso. Puoi quindi attivare quegli eventi da qualsiasi punto della tua app, incluso l'elemento dom html reale e ascoltarli da qualsiasi componente inoltrando gli elementi richiesti da quel componente.

Ext.define('Lib.MessageBus', {
    extend: 'Ext.util.Observable',

    constructor: function() {
        this.addEvents(
            /*
             * describe the event
             */
                  "eventname"

            );
        this.callParent(arguments);
    }
});

Quindi puoi, da qualsiasi altro componente:

 this.relayEvents(MesageBus, ['event1', 'event2'])

E sparali da qualsiasi componente o elemento dom:

 MessageBus.fireEvent('event1', somearg);

 <input type="button onclick="MessageBus.fireEvent('event2', 'somearg')">

A titolo informativo, this.addEvents è stato deprecato a partire da EXT JS 5.0. Quindi non è necessario aggiungere eventi ora
Ajay Sharma

11

Solo altre due cose che ho trovato utili da sapere, anche se non fanno parte della domanda, davvero.

È possibile utilizzare il relayEventsmetodo per indicare a un componente di ascoltare determinati eventi di un altro componente e quindi attivarli di nuovo come se provenissero dal primo componente. I documenti API forniscono l'esempio di una griglia che inoltra l' loadevento store . È abbastanza utile quando si scrivono componenti personalizzati che incapsulano diversi sottocomponenti.

Al contrario, vale a dire passare eventi ricevuti da un componente incapsulante mycmpa uno dei suoi sottocomponenti subcmp, può essere fatto in questo modo

mycmp.on('show' function (mycmp, eOpts)
{
   mycmp.subcmp.fireEvent('show', mycmp.subcmp, eOpts);
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.