ExtJS入门之事件(fireEvent)

来源:互联网 发布:什么叫做数据库查询 编辑:程序博客网 时间:2024/05/20 16:37
ExtJS入门之事件(fireEvent)
 收藏
 
  • 发表于 2年前 
  • 阅读 9277 
  • 收藏 8 
  • 点赞 0 
  • 评论 0
摘要: 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'thisthis.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'thisthis.activeRecord, this.animateTarget);        // Clear phantom and modified states.        this.activeRecord.commit();    },        // private    onDelete: function(){        this.fireEvent('eventdelete'thisthis.activeRecord, this.animateTarget);    }});

0 0
原创粉丝点击