【问题标题】:Redefining ExtJS events and delegating to previous implementation重新定义 ExtJS 事件并委托给以前的实现
【发布时间】:2011-12-16 00:51:27
【问题描述】:

我继承了一个大型 ExtJS3 代码库,并且有一个 Ext.grid.CellSelectionModel 的 beforecellselect 的“基础”覆盖。我正在截断大量代码,但这应该提供一个总体思路:

Ext.override(Ext.grid.CellSelectionModel, {
    init:function() {
        Ext.grid.CellSelectionModel.superclass.init.apply(this, arguments);

        if (this.unselectableColumns || this.visuallyMimicRowSelection || this.colSpecificHandlers){
        this.on('beforecellselect', function(selModel, rowIndex, columnIndex){
            //etcetera

然而,随后我们将实例化一个 CellSelectionModel,并在其上指定一个 beforecellselect 侦听器,如下所示:

var sm = new Ext.grid.CellSelectionModel({
listeners: {
    beforecellselect : {
    fn: function(selModel, rowIndex, colIndex) {
            //etcetera

问题是,在新 CellSelectionModel 实例的侦听器中,我还需要调用覆盖中定义的侦听器。因为 ExtJS 似乎保留了一组同名事件侦听器,所以我可以按如下方式进行委托:

selModel.events.beforecellselect.listeners[1].fn.apply(selModel, arguments);

好的,我知道我不应该对索引进行硬编码。但除此之外,还有更好、更 ExtJS-y 的方法吗?

【问题讨论】:

  • 监听器被添加(从监听器在你提到的监听器数组中可以看出),而不是被替换,所以你不需要做任何事情来调用原始监听器。事件触发时应调用所有侦听器。我认为覆盖可能有问题。

标签: extjs datagrid event-handling dom-events extjs3


【解决方案1】:

在您的情况下,如果您知道它将是一个将在构造函数之外使用的函数, 我建议将事件处理函数添加为 CellSelectionModel 的方法 实例,如下图:

    Ext.override(Ext.grid.CellSelectionModel, {
        init:function() {
            Ext.grid.CellSelectionModel.superclass.init.apply(this, arguments);
            this.customBeforeCellSelect = function(selModel, rowIndex, colIndex) {
                // etcetera
            };
            if (this.unselectableColumns
                || this.visuallyMimicRowSelection
                || this.colSpecificHandlers) {
                this.on('beforecellselect', this.customBeforeCellSelect, this);
            }
    });

    var sm = new Ext.grid.CellSelectionModel({
        listeners: {
            beforecellselect : {
                fn: function(selModel, rowIndex, colIndex) {
                    selModel.customBeforeCellSelect.apply(selModel, arguments);
                },
                scope: sm
            }
        }
    });

但是,请记住,您将事件处理程序附加到覆盖构造函数中的 beforecellselect 事件,因此如果您在特定实例 listeners 中的 beforecellselect 期间再次调用此事件处理程序函数,那么您最终将执行连续两次相同的功能。

出于效率考虑,您可以将自定义处理程序移至Ext.grid.CellSelectionModel 的原型,即,而不是将customBeforeCellSelect 放在init 内的单个实例上。请执行以下操作以实现此目的:

    Ext.grid.CellSelectionModel.prototype.customerBeforeCellSelect =
        function(selModel, rowIndex, colIndex) {
            // etcetera
    };

您可以在override 语句之后添加上述行。

【讨论】:

  • 我怀疑这是另一种方法,它肯定不那么脆弱。然而,这是我的前半周合同,我想在他们看到我修改他们的基本覆盖之前建立一定的信心。我们会看看是否有其他人以其他方式回答,但如果没有,我应该尽快接受您的回答。
  • 我忘了在原始答案中考虑效率。我已经更新了答案以解决这个问题。添加在答案的底部。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-05
  • 2016-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多