在没有处理程序引用的情况下覆盖侦听器,可以在 Ext.data.store 上访问(可能是私有的)事件 属性 吗?

Overwrite listener without handler reference, is it ok to access the (possibly private) events property on a Ext.data.store?

我正在努力替换 Ext.data.Store 加载事件处理程序。

代码块中的变量 me 每次都不同,但 me.store 是相同的(通过 StoreManager.lookup 获得)。我希望商店事件侦听器更新各种 me 引用。我能找到的最好方法是添加另一个侦听器(并删除旧的,因为我不再需要它了)

我无法使用 un / removeListener 即它没有效果。

我发现我可以通过访问 me.store.events 并从加载事件中弹出侦听器来替换它。然而,这感觉很糟糕,它可能使代码依赖于特定的 ExtJS 版本 (4.2),因为我不知道它是否是私有的 属性。

另外 me.store.hasListeners[[=​​27=]] 没有收到通知,所以它只是有帮助,因为它删除了实际的侦听器,但不是以预期的方式。文档没有提到它,但我想知道它是否可能是可以自由访问的继承 属性。

对于我所采用的工作方法,是否有任何替代方案?我可以在不引用处理程序的情况下删除事件的所有事件处理程序吗?还是我缺少更简单的方法?

    var me =  this; // an enriched Ext.form.FormPanel,  different every time code runs
    me.store //obtained via StoreManger.lookup - so the same every time
    me.storeLoaded = function (store, records,successful, opts) {
        // some code to select a record from records and use it  
        me.loadRecord(record);
        } 
    };

    if (!me.store.hasListener('load')) {
        me.store.on('load', me.storeLoaded);
    } else{
        //tried this, but it doesn't remove it, probably because me.storeLoaded is different each time (parentForm is different)
        me.store.un('load', me.storeLoaded);

        //this feels hacky, i couldn't find out if events is a private property
        if (me.store.events && me.store.events['load']){
            me.store.events['load'].listeners.pop()
        }
        me.store.on('load', me.storeLoaded);
    }

实现 adding/removing 侦听器的最简单方法是使用 destroyable 参数,如 addListener 函数中所述。这样,您始终可以确定删除了哪一个。

示例:

setActive:function(cmp) {
    cmp.myActiveListeners = cmp.eventStore.on({
        destroyable: true,
        load:cmp.refreshStores,
        filterchange:cmp.refreshStores,
        scope:cmp
    });
},
setInactive:function(cmp) {
    Ext.destroy(cmp.myActiveListeners);
},

我不建议盲目删除所有侦听器,因为它们可能会被您稍后添加的其他组件(例如组合框)添加。追踪这些错误会让你长出不少白发。

我在 this article ExtJS overwrite listener:

中找到了答案

Sometimes you need to overwrite an event listener in ExtJS. Usually listeners are registered like this myStore.on('load', this.myFunction, this); then to remove our previously registered listener, all we have to do is call un (which is an alias for removeListener): myStore.un('load', this.myFunction, this);

But, what happens when you don't know what function is registered? Sometimes you will not have a reference to the original function that was registered. This situation may arise if there is code that exists in a different flow or may even come as a package! If that is true, the you may not be able to get a reference to the javascript function or edit the existing code. In this case, we will have to look at all of the functions that are registered for this event. We can then remove the listeners just for a certain event by calling clearListeners.

clearListeners 是我一直在寻找的方法。

他似乎使用 events 属性 所以我认为这是一个有效的用途。在我的例子中可以翻译成:

me.store.events.load.clearListeners()

但是,由于我只会在这个特定的商店上使用加载事件,所以我将简单地调用它们。

me.store.clearListeners()

感谢亚历山大,建议不要删除所有真正帮助我找到文章的听众。但是我仍然会采用他的解决方案,即使它污染了商店对象,因为我更喜欢它而不是清除商店上的所有听众,即使只是针对特定事件。