Jelaskan penanganan acara ExtJS 4

130

Saya baru-baru ini mulai belajar ExtJS, dan kesulitan memahami bagaimana menangani Acara. Saya tidak memiliki pengalaman dari versi ExtJS sebelumnya.

Dari membaca berbagai manual, panduan, dan halaman dokumentasi, saya telah menemukan cara menggunakannya, tetapi saya tidak jelas bagaimana cara kerjanya. Saya telah menemukan beberapa tutorial untuk versi ExtJS yang lebih lama, tetapi saya tidak yakin bagaimana penerapannya di ExtJS 4.

Saya secara khusus mencari "kata terakhir" pada hal-hal seperti

  • argumen apa yang bisa dilewati oleh fungsi penanganan acara? Apakah ada seperangkat argumen yang selalu dilewati?
  • bagaimana cara mendefinisikan acara khusus untuk komponen khusus yang kami tulis? bagaimana kita bisa memecat acara adat ini?
  • apakah nilai balik (benar / salah) memengaruhi bagaimana peristiwa itu terjadi? Jika tidak, bagaimana kita bisa mengendalikan peristiwa yang menggelegak dari dalam, atau di luar pengendali acara?
  • Adakah cara standar untuk mendaftarkan pendengar acara? (Saya telah menemukan dua cara yang berbeda sampai sekarang, dan saya tidak yakin mengapa setiap metode digunakan).

Sebagai contoh, pertanyaan ini membuat saya percaya bahwa penangan event dapat menerima beberapa argumen. Saya telah melihat tutorial lain di mana hanya ada dua argumen ke pawang. Perubahan apa?

jrharshath
sumber
2
Hanya memperhatikan ... di luar topik?
jrharshath
12
88 Suara positif pada pertanyaan, 155 suara positif pada jawaban pertama dan Andrew yang hebat dan perkasa memutuskan bahwa ini bukan topik. Perjalanan kekuatan yang serius sedang terjadi!
boatcoder
3
Saya telah memilih untuk membuka kembali pertanyaan ini karena jawaban di sini adalah tambang emas. Saya telah mengedit pertanyaan agar lebih sesuai dengan gaya Q dan A.
Makan siang
1
Harap buka kembali pertanyaan ini karena sangat membantu & pertanyaan asli. jadi secara membabi buta kita tidak bisa menutupnya.
Piyush Dholariya
2
Ini adalah pertanyaan yang ditulis dengan baik, dan saya tidak melihat alasan untuk menutupnya. Menyebut topik ini tidak masuk akal. Memilih untuk dibuka kembali.
Mike Fuchs

Jawaban:

222

Mari kita mulai dengan menjelaskan penanganan acara elemen DOM.

Penanganan event simpul DOM

Pertama-tama Anda tidak ingin bekerja dengan simpul DOM secara langsung. Sebaliknya Anda mungkin ingin memanfaatkan Ext.Elementantarmuka. Untuk tujuan menugaskan penangan acara, Element.addListenerdan Element.on(ini adalah setara) dibuat. Jadi, misalnya, jika kita memiliki html:

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

dan kami ingin menambahkan clickpengendali acara.
Mari kita ambil Element:

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

Sekarang mari kita periksa dokumen untuk clickacara. Handler-nya mungkin memiliki tiga parameter:

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

Mengetahui semua hal ini dapat kami berikan penangan:

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

Penanganan acara widget

Penanganan acara widget sangat mirip dengan penanganan acara simpul DOM.

Pertama-tama, penanganan acara widget diwujudkan dengan menggunakan Ext.util.Observablemixin. Untuk menangani acara dengan benar, widget Anda harus bersaing Ext.util.Observablesebagai mixin. Semua widget Ext.util.Observablebawaan (seperti Panel, Form, Tree, Grid, ...) telah sebagai mixin secara default.

Untuk widget ada dua cara menetapkan penangan. Yang pertama - digunakan pada metode (atau addListener). Misalnya, buat Buttonwidget dan tetapkan clickacara untuknya. Pertama-tama Anda harus memeriksa dokumen acara untuk argumen penangan:

klik (Ext.button.Tombol ini, Event e, Object eOpts)

Sekarang mari kita gunakan 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);
});

Cara kedua adalah menggunakan konfigurasi pendengar 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);
    }
  }
});

Perhatikan bahwa Buttonwidget adalah jenis widget khusus. Acara klik dapat ditetapkan untuk widget ini dengan menggunakan handlerkonfigurasi:

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

Acara kustom diaktifkan

Pertama-tama Anda perlu mendaftarkan suatu acara menggunakan metode addEvents :

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

Menggunakan addEventsmetode ini opsional. Seperti komentar untuk metode ini mengatakan tidak perlu menggunakan metode ini tetapi menyediakan tempat untuk dokumentasi acara.

Untuk memecat acara Anda, gunakan metode fireEvent :

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

arg1, arg2, arg3, /* ... */akan diteruskan ke handler. Sekarang kami dapat menangani acara Anda:

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

Perlu disebutkan bahwa tempat terbaik untuk memasukkan panggilan metode addEvents adalah metode widget initComponentketika Anda mendefinisikan widget baru:

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

Mencegah terjadinya gelembung

Untuk mencegah gelembung Anda bisa return falseatau gunakan Ext.EventObject.preventDefault(). Untuk mencegah penggunaan tindakan default browser Ext.EventObject.stopPropagation().

Sebagai contoh, mari kita tetapkan event handler klik ke tombol kita. Dan jika tidak tombol kiri diklik mencegah tindakan browser default:

myButton.on('click', function(btn, e){
  if (e.button !== 0)
    e.preventDefault();
});
Pria Molekuler
sumber
3
ini, keserakahan, tetapi apakah ada cara untuk melakukan hal "addEvents" melalui beberapa konfigurasi? :)
jrharshath
@ jrharshath, sejauh yang saya tahu, sayangnya, tidak ada cara untuk melakukan itu melalui konfigurasi.
Manusia Molekuler
bagaimana cara membuat ini -'myspecialevent1 ', saya melihat Anda telah melampirkannya dan menanganinya tetapi bagaimana kita membuat ini?
Hei Sekarang
1
Jawaban yang brilian! Saya baru mengenal ExtJs dan sedang mencari cara untuk mereferensikan elemen apa pun di halaman dan menggunakan event handler pada mereka, seperti halnya jQuery. Anda mengajari saya untuk! Terima kasih!
Rutwick Gangurde
1
sedikit kesalahan di bagian "Mencegah peristiwa menggelegak". stopPropagation digunakan untuk mencegah bubling acara, dan preventDefault digunakan untuk mencegah perilaku / tindakan default.
MatRt
44

Menembak berbagai aplikasi

Cara membuat pengontrol berbicara satu sama lain ...

Selain jawaban yang sangat bagus di atas saya ingin menyebutkan peristiwa aplikasi luas yang dapat sangat berguna dalam pengaturan MVC untuk memungkinkan komunikasi antara pengontrol. (extjs4.1)

Katakanlah kita memiliki Stasiun pengontrol (contoh Sencha MVC) dengan kotak pilih:

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

Ketika kotak pilih memicu perubahan acara, fungsi onStationSelecttersebut diaktifkan.

Dalam fungsi itu kita melihat:

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

Ini membuat dan menjalankan aplikasi di seluruh acara yang dapat kita dengarkan dari pengontrol lain.

Dengan demikian di pengontrol lain kita sekarang bisa tahu kapan kotak pilih stasiun telah diubah. Ini dilakukan melalui mendengarkan this.application.onsebagai berikut:

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

Jika kotak pilih telah diubah, kami sekarang menjalankan fungsi onStationStartdi controller Songjuga ...

Dari dokumen Sencha:

Acara aplikasi sangat berguna untuk acara yang memiliki banyak pengontrol. Alih-alih mendengarkan acara tampilan yang sama di masing-masing pengendali ini, hanya satu pengendali yang mendengarkan acara tayangan dan menjalankan acara di seluruh aplikasi yang dapat didengarkan yang lain. Ini juga memungkinkan pengontrol untuk berkomunikasi satu sama lain tanpa mengetahui atau tergantung pada keberadaan masing-masing.

Dalam kasus saya: Mengklik simpul pohon untuk memperbarui data di panel kisi.

Perbarui 2016 berkat @ gm2008 dari komentar di bawah:

Dalam hal memecat acara khusus aplikasi, ada metode baru sekarang setelah ExtJS V5.1 diterbitkan, yang menggunakan Ext.GlobalEvents.

Saat Anda memadamkan acara, Anda dapat menghubungi: Ext.GlobalEvents.fireEvent('custom_event');

Ketika Anda mendaftarkan pawang acara, Anda menelepon: Ext.GlobalEvents.on('custom_event', function(arguments){/* handler codes*/}, scope);

Metode ini tidak terbatas pada pengontrol. Komponen apa pun dapat menangani acara kustom dengan menempatkan objek komponen sebagai cakupan parameter input.

Ditemukan di Sencha Docs: MVC Bagian 2

mahatmanich
sumber
1
Dalam hal memecat acara khusus aplikasi, ada metode baru sekarang setelah ExtJS V5.1 diterbitkan, yang menggunakan Ext.GlobalEvents. Saat Anda memecat suatu acara, Anda menelepon Ext.GlobalEvents.fireEvent('custom_event');Saat Anda mendaftarkan pawang acara tersebut, Anda memanggil Ext.GlobalEvents.on('custom_event', function(arguments){/* handler codes*/}, scope};Here is a fiddle . Metode ini tidak terbatas pada pengontrol. Komponen apa pun dapat menangani acara kustom dengan menempatkan objek komponen sebagai parameter input scope. Pertanyaannya harus dibuka kembali.
gm2008
15

Satu lagi trik untuk pendengar acara pengontrol.

Anda dapat menggunakan wildcard untuk menonton acara dari komponen apa pun:

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

Hanya ingin menambahkan beberapa pence ke jawaban yang sangat baik di atas: Jika Anda mengerjakan pra Extjs 4.1, dan tidak memiliki acara aplikasi yang luas tetapi membutuhkannya, saya telah menggunakan teknik yang sangat sederhana yang mungkin membantu: Membuat objek sederhana memperluas Observable, dan menentukan setiap peristiwa aplikasi yang Anda butuhkan di dalamnya. Anda kemudian dapat memecat acara tersebut dari mana saja di aplikasi Anda, termasuk elemen dom html aktual dan mendengarkannya dari komponen apa pun dengan menyampaikan elemen yang diperlukan dari komponen itu.

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

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

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

Maka Anda dapat, dari komponen lain:

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

Dan memecat mereka dari komponen atau elemen dom:

 MessageBus.fireEvent('event1', somearg);

 <input type="button onclick="MessageBus.fireEvent('event2', 'somearg')">
Harel
sumber
Sekadar informasi, this.addEvents sudah tidak digunakan lagi mulai dari EXT JS 5.0. Jadi tidak perlu menambahkan acara sekarang
Ajay Sharma
11

Hanya dua hal lagi yang menurut saya bermanfaat untuk diketahui, walaupun itu bukan bagian dari pertanyaan, sungguh.

Anda dapat menggunakan relayEventsmetode ini untuk memberi tahu komponen untuk mendengarkan acara tertentu dari komponen lain dan kemudian memecatnya lagi seolah-olah mereka berasal dari komponen pertama. API API memberikan contoh kisi yang menyampaikan loadperistiwa toko . Sangat berguna ketika menulis komponen khusus yang merangkum beberapa sub-komponen.

Cara sebaliknya, yaitu meneruskan peristiwa yang diterima oleh komponen enkapsulasi mycmpke salah satu sub-komponennya subcmp, dapat dilakukan seperti ini

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