Wyjaśnij obsługę zdarzeń ExtJS 4
Ostatnio zacząłem uczyć się ExtJS i mam problemy ze zrozumieniem, jak obsługiwać wydarzenia. Nie mam doświadczenia z poprzednimi wersjami ExtJS.
Czytając różne podręczniki, przewodniki i strony dokumentacji, odkryłem, jak z niego korzystać, ale nie jestem pewien, jak to działa. Znalazłem kilka samouczków dla starszych wersji ExtJS, ale nie jestem pewien, jak mają zastosowanie w ExtJS 4.
Szukam konkretnie "ostatniego słowa" o rzeczach jak
- jakie argumenty przekazuje funkcja obsługi zdarzeń? Czy istnieje standardowy zestaw args, który zawsze przechodzi?
- Jak zdefiniować niestandardowe zdarzenia dla niestandardowych komponentów, które piszemy? jak możemy odpalić te niestandardowe wydarzenie?
- czy wartość zwracana (true / false) ma wpływ na pęcherzyki zdarzeń? Jeśli nie, w jaki sposób możemy kontrolować bulgoczenie zdarzeń z wewnątrz lub poza obsługą zdarzeń?
- czy istnieje standardowy sposób rejestracji słuchaczy zdarzeń? (Natknąłem się na dwa różne sposoby do tej pory, i nie jestem pewien, dlaczego każda metoda została użyta).
Na przykład, to pytanie prowadzi mnie do przekonania, że obsługa zdarzeń może otrzymać sporo argumentów. Widziałem inne tutoriale, w których są tylko dwa argumenty do prowadzącego. Jakie zmiany?
5 answers
Zacznijmy od opisu obsługi zdarzeń elementów DOM.
Obsługa zdarzeń węzła DOM
Przede wszystkim nie chciałbyś pracować bezpośrednio z węzłem DOM. Zamiast tego prawdopodobnie chciałbyś wykorzystać Ext.Element
interfejs. Do celów przypisania programów obsługi zdarzeń, Element.addListener
oraz Element.on
(są równoważne) zostały stworzone. Tak więc, na przykład, jeśli mamy html:
<div id="test_node"></div>
I chcemy dodać click
obsługę zdarzenia.
Odzyskajmy Element
:
var el = Ext.get('test_node');
Teraz sprawdźmy dokumenty dla click
wydarzenie. Może mieć trzy parametry:
Click (Ext.EventObject e, HTMLElement t, Object eOpts)
Znając to wszystko możemy przypisać obsługę:
// event name event handler
el.on( 'click' , function(e, t, eOpts){
// handling event here
});
Obsługa widgetów
Obsługa zdarzeń widgetów jest bardzo podobna do obsługi zdarzeń węzłów DOM.
Przede wszystkim obsługa zdarzeń widgetów jest realizowana poprzez wykorzystanie Ext.util.Observable
mixin. Aby poprawnie obsłużyć zdarzenia, widget musi zawierać Ext.util.Observable
jako mixin. Wszystkie wbudowane widżety (takie jak Panel, formularz, drzewo, Siatka,...) domyślnie posiada Ext.util.Observable
jako mixin.
Dla widżetów są dwa sposoby przypisywania programów obsługi. Pierwszym - jest użycie na metodzie (lub addListener
). Stwórzmy na przykład widżet Button
i przypiszmy do niego Zdarzenie click
. Po pierwsze należy sprawdzić dokumenty zdarzenia pod kątem argumentów Handlera:
Click (Ext.guzik.Button this, Event e, Obiekt eOpts)
Teraz użyjmy 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);
});
Drugim sposobem jest użycie widgetu słuchaczy 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);
}
}
});
Zauważ, że Button
widget jest specjalnym rodzajem widżetów. Zdarzenie Click można przypisać do tego widżetu za pomocą 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);
}
});
Niestandardowe odpalanie zdarzeń
Najpierw musisz zarejestrować wydarzenie używając metody addEvents :
myButton.addEvents('myspecialevent1', 'myspecialevent2', 'myspecialevent3', /* ... */);
Użycie metody addEvents
jest opcjonalne. Jako komentarze do tej metody powiedzmy, że nie ma potrzeby stosowania tej metody, ale zapewnia ona miejsce na dokumentację zdarzeń.
Aby odpalić Zdarzenie użyj metody fireEvent :
myButton.fireEvent('myspecialevent1', arg1, arg2, arg3, /* ... */);
arg1, arg2, arg3, /* ... */
/ align = "left" / Teraz możemy obsłużyć Twoje wydarzenie:
myButton.on('myspecialevent1', function(arg1, arg2, arg3, /* ... */) {
// event handling here
console.log(arg1, arg2, arg3, /* ... */);
});
Warto wspomnieć, że najlepszym miejscem do wstawiania addevents wywołania metody jest metoda initComponent
widgetu podczas definiowania nowego widgetu:
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 */ });
Zapobieganie bąbelkom zdarzeń
Aby zapobiec bubbling można return false
lub użyć Ext.EventObject.preventDefault()
. Aby zapobiec domyślnemu działaniu przeglądarki, użyj Ext.EventObject.stopPropagation()
.
Na przykład przypisajmy obsługę zdarzenia click do naszego przycisku. A jeśli nie kliknięto lewego przycisku, zapobiegaj domyślnej akcji przeglądarki:
myButton.on('click', function(btn, e){
if (e.button !== 0)
e.preventDefault();
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-29 06:26:30
Strzelanie aplikacji wide events
Jak sprawić, by kontrolerzy ze sobą rozmawiali ...
Oprócz bardzo świetnej odpowiedzi powyżej chcę wspomnieć o zdarzeniach aplikacji, które mogą być bardzo przydatne w konfiguracji MVC, aby umożliwić komunikację między kontrolerami. (extjs4. 1)
Powiedzmy, że mamy stację kontrolera (przykłady Sencha MVC) z polem wyboru:
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]);
},
...
});
Gdy pole select uruchamia Zdarzenie change, Funkcja onStationSelect
jest zwolniony.
W obrębie tej funkcji widzimy:
this.application.fireEvent('stationstart', selection[0]);
To tworzy i wywołuje zdarzenie całej aplikacji, które możemy odsłuchać z dowolnego innego kontrolera.
Tak więc w innym kontrolerze możemy teraz wiedzieć, kiedy pole wyboru stacji zostało zmienione. Można to zrobić poprzez słuchanie this.application.on
w następujący sposób:
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?');
},
}
Jeśli pole wyboru zostało zmienione, uruchamiamy teraz funkcję onStationStart
również w kontrolerze Song
...
Od Sencha docs:
zdarzenia aplikacji są niezwykle przydatne dla zdarzeń, które mają wiele kontrolerów. Zamiast nasłuchiwać tego samego zdarzenia view w każdym z tych kontrolerów, tylko jeden kontroler nasłuchuje zdarzenia view i wywołuje zdarzenie dla całej aplikacji, którego inne mogą nasłuchać. Pozwala to również kontrolerom komunikować się ze sobą bez wiedzy o istnieniu innych lub w zależności od ich istnienia.
W moim przypadku: kliknięcie na węzeł drzewa w celu aktualizacji danych w Panel siatki.
Aktualizacja 2016 dzięki @ gm2008 z komentarzy poniżej:
Jeśli chodzi o uruchamianie niestandardowych zdarzeń w całej aplikacji, po opublikowaniu ExtJS V5.1 jest nowa metoda, która używa Ext.GlobalEvents
.
Kiedy odpalasz zdarzenia, możesz zadzwonić: Ext.GlobalEvents.fireEvent('custom_event');
Kiedy rejestrujesz obsługę zdarzenia, dzwonisz: Ext.GlobalEvents.on('custom_event', function(arguments){/* handler codes*/}, scope);
Ta metoda nie jest ograniczona do kontrolerów. Każdy komponent może obsłużyć niestandardowe zdarzenie poprzez umieszczenie obiekt komponentu jako zakres parametru wejściowego.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-21 11:05:46
Jeszcze jedna sztuczka dla Controller event listeners.
Możesz używać symboli wieloznacznych do oglądania zdarzenia z dowolnego komponentu:
this.control({
'*':{
myCustomEvent: this.doSomething
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-04 19:31:59
Chciałem tylko dodać kilka groszy do doskonałych odpowiedzi powyżej: Jeśli pracujesz na Pre Extjs 4.1 i nie masz zdarzeń w całej aplikacji, ale ich potrzebujesz, używam bardzo prostej techniki, która może pomóc: Utwórz prosty obiekt rozszerzający obserwowalny i zdefiniuj w nim dowolne zdarzenia o zasięgu aplikacji. Następnie można uruchomić te zdarzenia z dowolnego miejsca w aplikacji, w tym rzeczywisty element HTML dom i słuchać ich z dowolnego komponentu, przekazując wymagane elementy z tego komponent.
Ext.define('Lib.MessageBus', {
extend: 'Ext.util.Observable',
constructor: function() {
this.addEvents(
/*
* describe the event
*/
"eventname"
);
this.callParent(arguments);
}
});
Wtedy można, z dowolnego innego składnika:
this.relayEvents(MesageBus, ['event1', 'event2'])
I odpalić je z dowolnego elementu lub elementu dom:
MessageBus.fireEvent('event1', somearg);
<input type="button onclick="MessageBus.fireEvent('event2', 'somearg')">
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-02 19:44:02
Jeszcze tylko dwie rzeczy, które pomogły mi wiedzieć, nawet jeśli nie są częścią pytania, naprawdę.
Możesz użyć metody relayEvents
, aby powiedzieć komponentowi, aby nasłuchał pewnych zdarzeń innego komponentu, a następnie odpalił je ponownie, tak jakby pochodzą z pierwszego komponentu. Dokumentacja API zawiera przykład siatki przekazującej Zdarzenie store load
. Jest to bardzo przydatne przy pisaniu niestandardowych komponentów, które zawierają kilka podskładników.
Odwrotnie, tzn. przechodząc dalej zdarzenia odbierane przez komponent enkapsulujący mycmp
do jednego z jego podskładników subcmp
, można wykonać w ten sposób
mycmp.on('show' function (mycmp, eOpts)
{
mycmp.subcmp.fireEvent('show', mycmp.subcmp, eOpts);
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-12 09:21:11