ExtJS入门之事件(fireEvent)

事件是指一个特定的动作,这个动作可以针对HTML元素的,如keydown,keyup,mouseover, mouseout等,也可以是对于其它自定义的动作,如对Ajax异步请求的响应等。在ExtJS中,该如何处理呢?

1. 处理HTML元素的标准事件

HTML元素的标准事件是指mouseover、mousedown、click、blur、focus、change等能够直接对HTML元素发生的事件。在ExtJS中,这些事件的处理可以用如下的代码:

  • 注册一个事件处理函数使用: Ext.get(‘myElement‘).on(‘click‘, myHandler, myScope) myElement是要注册的元素的ID,click是事件的名称(注意,和HTML元素中的声明on

    XXX不同,这里不需要on),myHandler 是处理函数的函数名称,myScope是一个可选的参数,指定处理函数绑定的对象,也就是处理函数的作用域,如果不提供这个参数,则是默认的 window。

  • 撤销一个事件处理函数: Ext.get(‘myElement‘).un(‘click‘, myHandler, myScope) 参数的意义同上。

ExtJS会根据不同的浏览器进行相应的处理,根本不需要理会用户用的是什么浏览器。根据事件的不同,传给处理函数的参数也会不同,这个只能参考ExtJS的文档了,必要时还得参考源代码。

2. 处理自定义事件

在ExtJS中使用自定义事件,需要从Ext.util.Observable继承,示例代码如下:

Employee = function(name){
   this.name = name;
   this.addEvents({
      "fired" : true,
      "quit" : true
   });
}
Ext.extend(Employee, Ext.util.Observable, { ... });

在这段代码中,定义了一个Employee类,定义了fired和quit两个事件。如何触发这两个事件呢,基类Ext.util.Observable提供了触发自定义事件的方法fireEvent(eventName, arg1, arg2, ... argn), eventName是要触发的时间的名称(不区分大小写),后面的参数arg1,arg2等是要传给事件处理函数的参数。用上面的Employee类做示例,触发quit事件:

this.fireEvent(‘quit‘, this);

这行代码将触发quit事件,并将Empolyee类的实例传给quit事件的处理函数,quit事件的订阅可以采用如下代码:

function myHandler1(empolyee){ ... }
function myHandler2(empolyee){ ... }

var emp = new Empolyee(‘tom‘);
emp.on(‘quit‘, myHandler1);
emp.on(‘quit‘, myHandler2);

在上面的代码中,为quit事件注册了两个处理函数(myHandler1与myHandler),当quit事件被激发时,将会依次调用myHandler1和myHandler2两个函数。

值得注意的是,不管是HTML元素的标准事件还是自定义事件,如果为某个时间注册了多个处理函数,如前面的例子,如果myHandler1返回false 的话,则会取消在myHandler1之后注册的处理函数的执行,即该事件被取消,从而停止继续执行该事件的处理函数,而这个返回值false会作为事件 激发的结果,返回给empolyee,即:

var result = this.fireEvent(‘quit‘, this);
if (result === false) {
   alert(‘event canceled‘); //这里表示事件被某个处理函数取消
}
else {
   alert(‘event complete‘); // 这里表示事件执行完毕
}

通过Ext的自定义事件的机制,可以实现一对多的观察者模式,也可以实现一对一的绑定模式,这一点,在ExtJS的开发中是很重要的。

参考官方相关实现类:

/**
 * @class Ext.calendar.form.EventWindow
 * @extends Ext.Window
 * <p>A custom window containing a basic edit form used for quick editing of events.</p>
 * <p>This window also provides custom events specific to the calendar so that other calendar components can be easily
 * notified when an event has been edited via this component.</p>
 * @constructor
 * @param {Object} config The config object
 */
Ext.define(‘Ext.calendar.form.EventWindow‘, {
    extend: ‘Ext.window.Window‘,
    alias: ‘widget.eventeditwindow‘,
    
    requires: [
        ‘Ext.form.Panel‘,
        ‘Ext.calendar.util.Date‘,
        ‘Ext.calendar.data.EventModel‘,
        ‘Ext.calendar.data.EventMappings‘
    ],
    constructor: function(config) {
        var formPanelCfg = {
            xtype: ‘form‘,
            fieldDefaults: {
                msgTarget: ‘side‘,
                labelWidth: 65
            },
            frame: false,
            bodyStyle: ‘background:transparent;padding:5px 10px 10px;‘,
            bodyBorder: false,
            border: false,
            items: [{
                itemId: ‘title‘,
                name: Ext.calendar.data.EventMappings.Title.name,
                fieldLabel: ‘Title‘,
                xtype: ‘textfield‘,
                allowBlank: false,
                emptyText: ‘Event Title‘,
                anchor: ‘100%‘
            },
            {
                xtype: ‘daterangefield‘,
                itemId: ‘date-range‘,
                name: ‘dates‘,
                anchor: ‘100%‘,
                fieldLabel: ‘When‘
            }]
        };
    
        if (config.calendarStore) {
            this.calendarStore = config.calendarStore;
            delete config.calendarStore;
    
            formPanelCfg.items.push({
                xtype: ‘calendarpicker‘,
                itemId: ‘calendar‘,
                name: Ext.calendar.data.EventMappings.CalendarId.name,
                anchor: ‘100%‘,
                store: this.calendarStore
            });
        }
    
        this.callParent([Ext.apply({
            titleTextAdd: ‘Add Event‘,
            titleTextEdit: ‘Edit Event‘,
            width: 600,
            autocreate: true,
            border: true,
            closeAction: ‘hide‘,
            modal: false,
            resizable: false,
            buttonAlign: ‘left‘,
            savingMessage: ‘Saving changes...‘,
            deletingMessage: ‘Deleting event...‘,
            layout: ‘fit‘,
    
            defaultFocus: ‘title‘,
            onEsc: function(key, event) {
                        event.target.blur(); // Remove the focus to avoid doing the validity checks when the window is shown again.
                        this.onCancel();
                    },
            fbar: [{
                xtype: ‘tbtext‘,
                text: ‘<a href="#" id="tblink">Edit Details...</a>‘
            },
            ‘->‘,
            {
                itemId: ‘delete-btn‘,
                text: ‘Delete Event‘,
                disabled: false,
                handler: this.onDelete,
                scope: this,
                minWidth: 150,
                hideMode: ‘offsets‘
            },
            {
                text: ‘Save‘,
                disabled: false,
                handler: this.onSave,
                scope: this
            },
            {
                text: ‘Cancel‘,
                disabled: false,
                handler: this.onCancel,
                scope: this
            }],
            items: formPanelCfg
        },
        config)]);
    },
    // private
    newId: 10000,
    // private
    initComponent: function() {
        this.callParent();
        this.formPanel = this.items.items[0];
        this.addEvents({
            /**
             * @event eventadd
             * Fires after a new event is added
             * @param {Ext.calendar.form.EventWindow} this
             * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was added
             */
            eventadd: true,
            /**
             * @event eventupdate
             * Fires after an existing event is updated
             * @param {Ext.calendar.form.EventWindow} this
             * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was updated
             */
            eventupdate: true,
            /**
             * @event eventdelete
             * Fires after an event is deleted
             * @param {Ext.calendar.form.EventWindow} this
             * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was deleted
             */
            eventdelete: true,
            /**
             * @event eventcancel
             * Fires after an event add/edit operation is canceled by the user and no store update took place
             * @param {Ext.calendar.form.EventWindow} this
             * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was canceled
             */
            eventcancel: true,
            /**
             * @event editdetails
             * Fires when the user selects the option in this window to continue editing in the detailed edit form
             * (by default, an instance of {@link Ext.calendar.EventEditForm}. Handling code should hide this window
             * and transfer the current event record to the appropriate instance of the detailed form by showing it
             * and calling {@link Ext.calendar.EventEditForm#loadRecord loadRecord}.
             * @param {Ext.calendar.form.EventWindow} this
             * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} that is currently being edited
             */
            editdetails: true
        });
    },
    // private
    afterRender: function() {
        this.callParent();
        this.el.addCls(‘ext-cal-event-win‘);
        Ext.get(‘tblink‘).on(‘click‘, this.onEditDetailsClick, this);
        
        this.titleField = this.down(‘#title‘);
        this.dateRangeField = this.down(‘#date-range‘);
        this.calendarField = this.down(‘#calendar‘);
        this.deleteButton = this.down(‘#delete-btn‘);
    },
    
    // private
    onEditDetailsClick: function(e){
        e.stopEvent();
        this.updateRecord(this.activeRecord, true);
        this.fireEvent(‘editdetails‘, this, this.activeRecord, this.animateTarget);
    },
    /**
     * Shows the window, rendering it first if necessary, or activates it and brings it to front if hidden.
     * @param {Ext.data.Record/Object} o Either a {@link Ext.data.Record} if showing the form
     * for an existing event in edit mode, or a plain object containing a StartDate property (and 
     * optionally an EndDate property) for showing the form in add mode. 
     * @param {String/Element} animateTarget (optional) The target element or id from which the window should
     * animate while opening (defaults to null with no animation)
     * @return {Ext.Window} this
     */
    show: function(o, animateTarget) {
        // Work around the CSS day cell height hack needed for initial render in IE8/strict:
        var me = this,
            anim = (Ext.isIE8 && Ext.isStrict) ? null: animateTarget,
            M = Ext.calendar.data.EventMappings;
        this.callParent([anim, function(){
            me.titleField.focus(true);
        }]);
        
        this.deleteButton[o.data && o.data[M.EventId.name] ? ‘show‘: ‘hide‘]();
        var rec,
        f = this.formPanel.form;
        if (o.data) {
            rec = o;
            this.setTitle(rec.phantom ? this.titleTextAdd : this.titleTextEdit);
            f.loadRecord(rec);
        }
        else {
            this.setTitle(this.titleTextAdd);
            var start = o[M.StartDate.name],
                end = o[M.EndDate.name] || Ext.calendar.util.Date.add(start, {hours: 1});
            rec = Ext.create(‘Ext.calendar.data.EventModel‘);
            rec.data[M.StartDate.name] = start;
            rec.data[M.EndDate.name] = end;
            rec.data[M.IsAllDay.name] = !!o[M.IsAllDay.name] || start.getDate() != Ext.calendar.util.Date.add(end, {millis: 1}).getDate();
            f.reset();
            f.loadRecord(rec);
        }
        if (this.calendarStore) {
            this.calendarField.setValue(rec.data[M.CalendarId.name]);
        }
        this.dateRangeField.setValue(rec.data);
        this.activeRecord = rec;
        return this;
    },
    // private
    roundTime: function(dt, incr) {
        incr = incr || 15;
        var m = parseInt(dt.getMinutes(), 10);
        return dt.add(‘mi‘, incr - (m % incr));
    },
    // private
    onCancel: function() {
        this.cleanup(true);
        this.fireEvent(‘eventcancel‘, this);
    },
    // private
    cleanup: function(hide) {
        if (this.activeRecord && this.activeRecord.dirty) {
            this.activeRecord.reject();
        }
        delete this.activeRecord;
        if (hide === true) {
            // Work around the CSS day cell height hack needed for initial render in IE8/strict:
            //var anim = afterDelete || (Ext.isIE8 && Ext.isStrict) ? null : this.animateTarget;
            this.hide();
        }
    },
    // private
    updateRecord: function(record, keepEditing) {
        var fields = record.fields,
            values = this.formPanel.getForm().getValues(),
            name,
            M = Ext.calendar.data.EventMappings,
            obj = {};
        fields.each(function(f) {
            name = f.name;
            if (name in values) {
                obj[name] = values[name];
            }
        });
        
        var dates = this.dateRangeField.getValue();
        obj[M.StartDate.name] = dates[0];
        obj[M.EndDate.name] = dates[1];
        obj[M.IsAllDay.name] = dates[2];
        record.beginEdit();
        record.set(obj);
        
        if (!keepEditing) {
            record.endEdit();
        }
        return this;
    },
    
    // private
    onSave: function(){
        if(!this.formPanel.form.isValid()){
            return;
        }
        if(!this.updateRecord(this.activeRecord)){
            this.onCancel();
            return;
        }
        this.fireEvent(this.activeRecord.phantom ? ‘eventadd‘ : ‘eventupdate‘, this, this.activeRecord, this.animateTarget);
        // Clear phantom and modified states.
        this.activeRecord.commit();
    },
    
    // private
    onDelete: function(){
        this.fireEvent(‘eventdelete‘, this, this.activeRecord, this.animateTarget);
    }
});
时间: 2024-08-07 12:59:29

ExtJS入门之事件(fireEvent)的相关文章

ExtJs之自定义事件

1.新建一个实践类 1 Employee = function(name) 2 { 3 4 this.name = name; 5 6 this.addEvents({ 7 8 "fired" : true, 9 10 "quit" : true 11 12 }); 13 14 } 15 16 Ext.extend(Employee, Ext.util.Observable,{}); 2.绑定相关事件,这里用的事件类本身的引用 TODO 考虑怎么用其他的对象 1 v

无废话ExtJs 入门教程十七[列表:GridPanel]

无废话ExtJs 入门教程十七[列表:GridPanel] extjs技术交流,欢迎加群(201926085) 在Extjs中,GridPanel用于数据显示,即我们平时说的列表页.在本节中,我们先对GridPanel有个基本的认识,后继过程再做Demo练习详细讲解在开发中的应用. 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/

无废话ExtJs 入门教程十四[文本编辑器:Editor]

无废话ExtJs 入门教程十四[文本编辑器:Editor] extjs技术交流,欢迎加群(201926085) ExtJs自带的编辑器没有图片上传的功能,大部分时候能够满足我们的需要. 但有时候这个功能还是需要的.我在这里对keeditor进行了整合. 首先要下载keeditor和上传时需要引用的LitJson.dll.由于ke的版本不同,我这里提供的下载文件只适用于当前整合代码,供参考. 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML

无废话ExtJs 入门教程十九[API的使用]

无废话ExtJs 入门教程十九[API的使用] extjs技术交流,欢迎加群(201926085) 首先解释什么是 API 来自百度百科的官方解释:API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件的以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节. ExtJs的Api必须部署到IIS上,ExtJS的API首页如下图所示: 左侧是搜索栏,可以搜索所有的Ext的组件,如上图

无废话ExtJs 入门教程三[窗体:Window组件]

无废话ExtJs 入门教程三[窗体:Window组件] extjs技术交流,欢迎加群(201926085) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/19

无废话ExtJs 入门教程五[文本框:TextField]

无废话ExtJs 入门教程五[文本框:TextField] extjs技术交流,欢迎加群(201926085) 继上一节内容,我们在表单里加了个两个文本框.如下所示代码区的第42行位置,items: [txtusername, txtpassword]. 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xht

无废话ExtJs 入门教程六[按钮:Button]

无废话ExtJs 入门教程六[按钮:Button] extjs技术交流,欢迎加群(201926085) 继上一节内容,我们在表单里加了个两个按钮“提交”与重置.如下所示代码区的第68行位置, buttons: [btnsubmit, btnreset]. 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xht

无废话ExtJs 入门教程四[表单:FormPanel]

无废话ExtJs 入门教程四[表单:FormPanel] extjs技术交流,欢迎加群(201926085) 继上一节内容,我们在窗体里加了个表单.如下所示代码区的第28行位置,items:form. 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&

EXTJS入门实例

最近了解了下EXTJS,想记录下来自己的成果,希望对刚入门EXT的同学有点帮助,首先来做个简单的实例. 一.去官网下载EXTJS包extjs5,这里采用的是5.0版本,下面就正式开启吧! 二.解压extjs包,找到 ext-all.js基础包(\ext-5.0.0\build): ext-all-debug.js基础包,开发的时候使用,报错会详细些(\ext-5.0.0\build): 选一个合适的主题,这里我使用crisp,找到ext-theme-crisp-all.css和images文件(