Объяснить обработку событий ExtJS 4



Я недавно начал изучать ExtJS, и у меня есть проблемы с пониманием того, как обрабатывать события. У меня нет опыта работы с любыми предыдущими версиями ExtJS.



из чтения различных руководств, руководств и страниц документации, я понял, как его использовать, но я не понимаю, как это работает. Я нашел несколько учебников для более старых версий ExtJS, но я не уверен, насколько они применимы в ExtJS 4.



Я специально смотрю на "последнее слово" о вещах как




  • какие аргументы передаются функции обработки событий? Есть ли стандартный набор аргументов, которые всегда проходят?

  • как определить пользовательские события для пользовательских компонентов мы пишем? как мы можем запустить эти пользовательские события?

  • влияет ли возвращаемое значение (true / false) на то, как пузырьки событий? Если нет, то как мы можем контролировать бурление событие изнутри, или снаружи обработчика событий?

  • есть стандартный способ регистрации прослушивателей событий? (Я столкнулся с двумя разными способами до сих пор, и я не уверен, почему каждый метод был использован).


например, этот вопрос заставляет меня полагать, что обработчик событий может получить довольно много аргументов. Я видел другие учебники, где есть только два аргумента для обработчика. Какие изменения?

1175   5  

5 ответов:

начнем с описания обработки событий элементов DOM.

обработка событий узла DOM

прежде всего, вы не хотели бы работать с узлом DOM напрямую. Вместо этого вы, вероятно, хотели бы использовать Ext.Element интерфейс. Для назначения обработчиков событий,Element.addListener и Element.on (они эквивалентны) были созданы. Так, например, если у нас есть HTML:

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

и мы хотим добавить click обработчик событий.
Давайте получим Element:

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

теперь давайте проверим документы на click событие. Это обработчик может иметь три параметра:

click (Ext.EventObject e, HTMLElement t, Object eOpts)

зная все это, мы можем назначить обработчик:

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

виджеты обработки событий

обработка событий виджетов очень похожа на обработку событий узлов DOM.

прежде всего, обработка событий виджетов осуществляется с помощью Ext.util.Observable mixin. Для того, чтобы правильно обрабатывать события ваш виджет должен containg Ext.util.Observable как миксина. Все встроенные виджеты (например, панель, форма, дерево, сетка, ...) имеет Ext.util.Observable как mixin по умолчанию.

для виджетов существует два способа назначения обработчиков. Первый - это использовать on метод (или addListener). Давайте, например, создадим Button виджет и назначить click событие к нему. Прежде всего, вы должны проверить документы события для Аргументов обработчика:

click (Ext.кнопка.Кнопка эта, событие e, объект eOpts)

теперь давайте использовать 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);
});

второй способ-использовать виджет слушатель 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);
    }
  }
});

обратите внимание, что Button виджет-это особый вид Виджеты. Событие Click может быть назначено этому виджету с помощью 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);
  }
});

запуск пользовательских событий

прежде всего вам нужно зарегистрировать событие с помощью addEvents способ:

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

С помощью addEvents метод не является обязательным. Поскольку комментарии к этому методу говорят, что нет необходимости использовать этот метод, но он предоставляет место для документации событий.

для запуска вашего события используйте fireEvent способ:

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

arg1, arg2, arg3, /* ... */ будет передан в обработчик. Теперь мы может обрабатывать ваше событие:

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

стоит отметить, что лучшее место для вставки addEvents вызов метода-это виджет initComponent метод при определении нового виджета:

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 */ });

предотвращение пузырящегося события

чтобы предотвратить пузырение вы можете return false или использовать Ext.EventObject.preventDefault(). Для предотвращения действия браузера по умолчанию используйте Ext.EventObject.stopPropagation().

например, давайте назначим событие щелчка обработчик к нашей кнопке. И если не левая кнопка была нажата предотвратить действие браузера по умолчанию:

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

запуск приложения широкие события

как заставить контроллеры говорить друг с другом ...

в дополнение к очень большому ответу выше я хочу упомянуть события широкого применения, которые могут быть очень полезны в настройке MVC для обеспечения связи между контроллерами. (extjs4.1)

допустим, у нас есть станция контроллера (примеры Sencha MVC) с полем выбора:

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

когда поле выбора запускает событие изменения, функция onStationSelect уволен.

в этой функции мы видим:

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

это создает и запускает широкое событие приложения, которое мы можем слушать с любого другого контроллера.

таким образом, в другом контроллере мы теперь можем знать, когда поле выбора станции было изменено. Это делается через прослушивание this.application.on следующим образом:

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

если поле выбора было изменено, мы теперь запускаем функцию onStationStart в контроллере Song также ...

из документов Сенча:

события приложения чрезвычайно полезны для событий, которые имеют много контроллеров. Вместо того чтобы прослушивать одно и то же событие представления в каждом из этих контроллеров, только один контроллер прослушивает событие представления и запускает событие всего приложения, которое могут прослушивать другие. Это также позволяет контроллерам общаться друг с другом, не зная или в зависимости от друг друга существование.

в моем случае: щелчок по узлу дерева для обновления данных в панели сетки.

обновление 2016 благодаря @gm2008 из комментариев ниже:

что касается запуска пользовательских событий в масштабах всего приложения, теперь есть новый метод после ExtJS V5. 1 публикуется, который использует Ext.GlobalEvents.

когда вы запускаете события, вы можете позвонить:Ext.GlobalEvents.fireEvent('custom_event');

когда вы регистрируете обработчик события, вы звоните: Ext.GlobalEvents.on('custom_event', function(arguments){/* handler codes*/}, scope);

этот метод не ограничивается контроллеров. Любой компонент может обрабатывать пользовательское событие, помещая объект компонента в область входных параметров.

найдено в Sencha Docs: MVC Part 2

еще один трюк для прослушивателей событий контроллера.

вы можете использовать подстановочные знаки для наблюдения за событием из любого компонента:

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

просто хотел добавить пару пенсов к отличным ответам выше: Если вы работаете над pre Extjs 4.1, и у вас нет широких событий приложения, но они нужны, я использую очень простой метод, который может помочь: Создайте простой объект, расширяющий наблюдаемое, и определите любые события приложения, которые могут вам понадобиться в нем. Затем вы можете запускать эти события из любого места вашего приложения, включая фактический элемент html dom и прослушивать их из любого компонента, передавая необходимые элементы из эта компонента.

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

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

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

тогда вы можете, из любого другого компонента:

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

и уволить их из любого компонента или элемента DOM:

 MessageBus.fireEvent('event1', somearg);

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

просто еще две вещи, которые я нашел полезными, чтобы знать, даже если они не являются частью вопроса, на самом деле.

можно использовать relayEvents метод, позволяющий компоненту прослушивать определенные события другого компонента, а затем запускать их снова, как если бы они исходили из первого компонента. В документах API приведен пример сетки, ретранслирующей хранилище load событие. Это очень удобно при написании пользовательских компонентов, которые включают несколько компонентов.

в другую сторону вокруг, т. е. передача событий, полученных инкапсулирующим компонентом mycmp к одному из его субкомпонентов subcmp, можно сделать такой

mycmp.on('show' function (mycmp, eOpts)
{
   mycmp.subcmp.fireEvent('show', mycmp.subcmp, eOpts);
});

Comments

    Ничего не найдено.