ExtJS 4 - 对callParent的异步回调抛出异常

时间:2013-05-05 11:11:10

标签: javascript extjs

我想在处理callParent()之前准备一些Json商店,然后它会抛出错误。

但是,me.callParent()在没有异步回调的情况下工作正常。

Ext.define('My.desktop.AppExt', {
    extend: 'Ext.ux.desktop.App',

    someStore: null,

    init: function() {
        var me = this;
        me.someStore = Ext.create('My.store.SomeStore');
        me.someStore.load({
            scope: this,
            url: 'some/json/url',
            callback: function(records, opt, success) {
                 if (success) {
                     me.callParent(); // BOOM! ERROR HERE
                 }
            }
        });
    }
});

ERROR:

第4245行未处理的异常,第17行//localhost/js/ext-all-debug.js

0x800a138f - JavaScript运行时错误:

无法获取未定义或空引用的属性“超类”

3 个答案:

答案 0 :(得分:6)

callParent依赖于上下文来调用正确的方法,所以如果你实际上没有从子类方法“直接”调用它,你需要手动调用它:

Ext.define('A', {
    foo: function(){
        console.log('foo', 'a');    
    }
});

Ext.define('B', {
    extend: 'A',
    bar: function(){
        this.self.superclass.foo.call(this);    
    }
});

Ext.onReady(function(){
    var o = new B();
    o.bar();
});

答案 1 :(得分:1)

为此目的的最佳解决方案是在callParent()函数中获取与parentMethod的链接,但不调用它:

/**
 * Returns reference to the parent class method. Works as {@link Ext.Base#callParent}, but doesn't invoke the
 * method.
 * @return {Function} Parent class method.
 */
getParentMethod: function() {
    var method,
        superMethod = (method = this.getParentMethod.caller) && (method.$previous ||
            ((method = method.$owner ? method : method.caller) && method.$owner.superclass[method.$name]));
    return superMethod;
},  


sampleMethod: function() {
    var parentMethod = this.getParentMethod();
    var parentArguments = arguments;
    someAsyncFunc(function() {
        parentMethod.apply(this, parentArguments); // calls parent.sampleMethod(...)
    }, this);
}

答案 2 :(得分:0)

我知道的一种方法是使用额外的参数,这表明应该调用父方法:

init: function(callParent) {
    if (callParent) {
        this.callParent();
    }
    var me = this;
    me.someStore = Ext.create('My.store.SomeStore');
    me.someStore.load({
        scope: this,
        url: 'some/json/url',
        callback: function(records, opt, success) {
             if (success) {
                 this.init(true);
             }
        }
    });
}

如果你使用this.self.superclass.init.call(this),只有在有人为你的班级创建孩子之后才会这样。 this.self.superclass指向实例的类的超类,因此它指向My.desktop.AppExt而不是Ext.ux.desktop.App。

更新于2016年8月24日:发布更智能的解决方案(请参阅我的另一个答案)。