ExtJS 4 olay işlemeyi açıklayın


130

Yakın zamanda ExtJS öğrenmeye başladım ve Olayları nasıl yöneteceğimi anlamakta güçlük çekiyorum. ExtJS'nin önceki sürümleriyle ilgili deneyimim yok.

Çeşitli kılavuzları, kılavuzları ve dokümantasyon sayfalarını okuyarak, onu nasıl kullanacağımı anladım, ancak nasıl çalıştığı konusunda net değilim. ExtJS'nin eski sürümleri için birkaç öğretici buldum, ancak ExtJS 4'te ne kadar uygulanabilir olduğundan emin değilim.

Özellikle aşağıdaki gibi şeylerle ilgili "son söz" e bakıyorum

  • bir olay işleme işlevi hangi bağımsız değişkenleri iletir? Her zaman geçilen standart bir dizi bağımsız değişken var mı?
  • yazdığımız özel bileşenler için özel olaylar nasıl tanımlanır? bu özel etkinliği nasıl tetikleyebiliriz?
  • dönüş değeri (doğru / yanlış) olayın baloncuğunu nasıl etkiler? Değilse, olay işleyicisinin içinden veya dışından köpürmeyi nasıl kontrol edebiliriz?
  • olay dinleyicilerini kaydetmenin standart bir yolu var mı? (Şimdiye kadar iki farklı yolla karşılaştım ve her yöntemin neden kullanıldığından emin değilim).

Örneğin, bu soru beni bir olay işleyicisinin epeyce argüman alabileceğine inanmaya yönlendiriyor. İşleyicinin sadece iki argümanı olduğu başka öğreticiler de gördüm. Hangi değişiklikler?


2
Konu dışı ... yeni mi fark ettiniz?
jrharshath

12
88 Soruya olumlu oy verir, 155 ilk cevaba olumlu oy verir ve yüce ve güçlü Andrew bunun konu dışı olduğuna karar verir. Ciddi güç yolculuğu devam ediyor!
boatcoder 04

3
Buradaki cevaplar altın madeni olduğu için bu soruyu yeniden açmaya oy verdim. Soruyu Q ve A stiline daha iyi uyacak şekilde düzenledim.
dbrin

1
Lütfen bu soruyu tekrar açın çünkü gerçekten yararlı ve gerçek bir sorudur. o kadar körü körüne kapatamayız ki onu.
Piyush Dholariya

2
Bu iyi yazılmış bir soru ve kapatmak için bir neden göremiyorum. Buna konu dışı demek saçma. Yeniden açılması için oy verildi.
Mike Fuchs

Yanıtlar:


222

DOM öğelerinin olay işlemesini açıklayarak başlayalım.

DOM düğümü olay işleme

Her şeyden önce doğrudan DOM düğümü ile çalışmak istemezsiniz. Bunun yerine, muhtemelen Ext.Elementarayüzü kullanmak istersiniz . Olay işleyicileri atamak amacıyla Element.addListenerve Element.on(bunlar eşdeğerdir) oluşturulmuştur. Öyleyse, örneğin, html'ye sahipsek:

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

ve clickolay işleyicisi eklemek istiyoruz .
Hadi geri alalım Element:

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

Şimdi clickolay için dokümanlara bakalım . İşleyicinin üç parametresi olabilir:

(Ext.EventObject e, HTMLElement t, Object eOpts) öğesine tıklayın

Tüm bunları bilerek işleyici atayabiliriz:

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

Widget olay yönetimi

Widgets olay işleme, DOM düğümleri olay işlemeye oldukça benzer.

Her şeyden önce, widget olay işleme Ext.util.Observablemixin kullanılarak gerçekleştirilir . Olayları düzgün bir şekilde işleyebilmek için, widget'ınız bir karışım Ext.util.Observableolarak içermelidir . Tüm yerleşik widget'ların (Panel, Form, Ağaç, Izgara, ... gibi) Ext.util.Observablevarsayılan olarak bir karışımı vardır .

Widget'lar için işleyici atamanın iki yolu vardır. İlki - yöntem (veya ) üzerinde kullanmaktır addListener. Örneğin, Buttonwidget oluşturalım ve clickona olay atayalım . Öncelikle eylemcinin argümanları için olayın belgelerine bakmalısınız:

(Ext.button.Button, Event e, Object eOpts)

Şimdi kullanalım 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);
});

İkinci yol, widget'ın dinleyici yapılandırmasını kullanmaktır :

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

ButtonWidget'ın özel bir tür widget olduğuna dikkat edin . Tıklama etkinliği, handleryapılandırma kullanılarak bu widget'a atanabilir :

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

Özel olayların tetiklenmesi

Öncelikle addEvents yöntemini kullanarak bir etkinlik kaydetmeniz gerekir :

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

addEventsYöntemi kullanmak isteğe bağlıdır. Bu yönteme ilişkin yorumların söylediği gibi, bu yöntemi kullanmaya gerek yoktur, ancak olay dokümantasyonu için yer sağlar.

Etkinliğinizi başlatmak için fireEvent yöntemini kullanın :

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

arg1, arg2, arg3, /* ... */işleyiciye aktarılacaktır. Şimdi etkinliğinizi halledebiliriz:

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

AddEvents yöntem çağrısını eklemek için en iyi yerin, initComponentyeni pencere öğesini tanımlarken widget'ın yöntemi olduğunu belirtmekte fayda var :

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

Olay köpürmesini önleme

Köpürmeyi önlemek için yapabilir return falseveya kullanabilirsiniz Ext.EventObject.preventDefault(). Tarayıcının varsayılan eylemini önlemek için Ext.EventObject.stopPropagation().

Örneğin düğmemize tıklama olay işleyicisi atayalım. Ve sol düğme tıklanmadıysa, varsayılan tarayıcı eylemini engelleyin:

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

3
açgözlülük bu, ama bazı yapılandırma yoluyla "addEvents" olayını yapmanın herhangi bir yolu var mı? :)
jrharshath

@jrharshath, bildiğim kadarıyla, ne yazık ki, bunu config aracılığıyla yapmanın bir yolu yok.
Moleküler Man

Bunları nasıl yaratırız -'myspecialevent1 ', onu eklediniz ve hallettiğinizi görüyorum ama bunları nasıl yaratacağız?
heyNow

1
Harika cevap! ExtJs'de yeniyim ve sayfadaki herhangi bir öğeye başvurmanın ve jQuery gibi olay işleyicilerini kullanmanın bir yolunu arıyordum. Bana öğrettin! Teşekkürler!
Rutwick Gangurde

1
"Olay köpürmesini önleme" bölümünde küçük hata. stopPropagation, olay köpürmesini önlemek için kullanılır ve preventDefault, varsayılan davranışı / eylemi önlemek için kullanılır.
MatRt

44

Uygulama genelindeki etkinlikleri tetikleme

Denetleyicilerin birbirleriyle konuşmasını sağlama ...

Yukarıdaki çok harika cevaba ek olarak, kontrolörler arasında iletişimi sağlamak için bir MVC kurulumunda çok faydalı olabilecek uygulama çapındaki olaylardan bahsetmek istiyorum. (Extjs4.1)

Bir seçim kutusu olan bir kontrol istasyonumuz (Sencha MVC örnekleri) olduğunu varsayalım:

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

Seçim kutusu bir değişiklik olayını tetiklediğinde, işlev çalıştırılır onStationSelect.

Bu işlevde şunları görüyoruz:

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

Bu, diğer herhangi bir denetleyiciden dinleyebileceğimiz bir uygulama çapında olay oluşturur ve tetikler.

Böylece başka bir kontrolörde, istasyon seçim kutusunun ne zaman değiştirildiğini artık bilebiliriz. Bu, this.application.onaşağıdaki gibi dinleyerek yapılır :

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çim kutusu değiştirildiyse, şimdi onStationStartdenetleyicideki işlevi Songde çalıştırıyoruz ...

Sencha belgelerinden:

Uygulama olayları, birçok denetleyiciye sahip olaylar için son derece kullanışlıdır. Bu denetleyicilerin her birinde aynı görünüm olayını dinlemek yerine, yalnızca bir denetleyici view olayını dinler ve diğerlerinin dinleyebileceği uygulama çapında bir olayı tetikler. Bu aynı zamanda kontrolörlerin birbirlerinin varlığından haberdar olmadan veya birbirlerinin varlığına bağlı olmadan birbirleriyle iletişim kurmasına izin verir.

Benim durumumda: Bir ızgara panelindeki verileri güncellemek için bir ağaç düğümüne tıklamak.

Aşağıdaki yorumlardan @ gm2008 sayesinde 2016'yı güncelleyin:

Uygulama çapında özel olayların tetiklenmesi açısından, ExtJS V5.1 yayınlandıktan sonra kullanılmakta olan yeni bir yöntem varExt.GlobalEvents .

Olayları tetiklediğinizde şunları arayabilirsiniz: Ext.GlobalEvents.fireEvent('custom_event');

Etkinliğin bir işleyicisini kaydettiğinizde şunları arayın: Ext.GlobalEvents.on('custom_event', function(arguments){/* handler codes*/}, scope);

Bu yöntem kontrolörlerle sınırlı değildir. Herhangi bir bileşen, bileşen nesnesini girdi parametresi kapsamı olarak koyarak özel bir olayı işleyebilir.

Sencha Dokümanlarında bulundu: MVC Bölüm 2


1
Uygulama çapında özel olayları tetikleme açısından, ExtJS V5.1 yayınlandıktan sonra artık Ext.GlobalEvents kullanan yeni bir yöntem var. Olayı tetiklediğinizde, çağırırsınız Olayın Ext.GlobalEvents.fireEvent('custom_event');bir işleyicisini kaydettiğinizde, Ext.GlobalEvents.on('custom_event', function(arguments){/* handler codes*/}, scope};İşte bir keman olduğunu çağırırsınız . Bu yöntem denetleyicilerle sınırlı değildir. Herhangi bir bileşen, bileşen nesnesini girdi parametresi olarak koyarak özel bir olayı işleyebilir scope. Soru yeniden açılmalıdır.
gm2008

15

Denetleyici olay dinleyicileri için bir numara daha.

Herhangi bir bileşenden bir etkinliği izlemek için joker karakterleri kullanabilirsiniz:

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

12

Yukarıdaki mükemmel cevaplara birkaç peni eklemek istedim: Extjs 4.1 öncesi üzerinde çalışıyorsanız ve uygulama çapında olaylara sahip değilseniz, ancak bunlara ihtiyacınız varsa, yardımcı olabilecek çok basit bir teknik kullanıyorum: basit nesne Gözlemlenebilir'i genişletir ve içinde ihtiyaç duyabileceğiniz tüm uygulama çapında olayları tanımlayın. Daha sonra bu olayları, gerçek html dom öğesi dahil olmak üzere uygulamanızın herhangi bir yerinden tetikleyebilir ve gerekli öğeleri o bileşenden aktararak herhangi bir bileşenden dinleyebilirsiniz.

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

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

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

Daha sonra herhangi bir bileşenden şunları yapabilirsiniz:

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

Ve onları herhangi bir bileşen veya dom öğesinden ateşleyin:

 MessageBus.fireEvent('event1', somearg);

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

Sadece bilgi amaçlı, this.addEvents, EXT JS 5.0'dan itibaren kullanımdan kaldırılmıştır. Yani şimdi etkinlik eklemenize gerek yok
Ajay Sharma

11

Sorunun bir parçası olmasalar bile bilmenin yararlı olduğunu düşündüğüm iki şey daha var.

relayEventsYöntemi, bir bileşene başka bir bileşenin belirli olaylarını dinlemesini ve ardından ilk bileşenden geliyormuş gibi yeniden ateşlemesini söylemek için kullanabilirsiniz . API belgeleri, mağaza loadolayını aktaran bir ızgara örneğini verir . Birkaç alt bileşeni kapsayan özel bileşenler yazarken oldukça kullanışlıdır.

Diğer bir yol, yani bir kapsülleyici bileşen tarafından alınan olayların mycmpalt bileşenlerinden birine aktarılması subcmpşu şekilde yapılabilir.

mycmp.on('show' function (mycmp, eOpts)
{
   mycmp.subcmp.fireEvent('show', mycmp.subcmp, eOpts);
});
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.