2

我想在处理之前准备一些 Json Store callParent(),然后它会引发错误。

但是,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
                 }
            }
        });
    }
});

错误:

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

0x800a138f - JavaScript 运行时错误:

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

4

3 回答 3

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();
});
于 2013-05-05T11:23:05.870 回答
2

为此目的的最佳解决方案是在 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);
}
于 2016-08-24T09:08:54.397 回答
0

One of the ways I know is to use extra parameter, that indicates that parent method should be called:

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);
             }
        }
    });
}

If you use this.self.superclass.init.call(this) it will be ok only until somebody will create child for your class. this.self.superclass points to superclass of instance's class, so it would points to My.desktop.AppExt instead of Ext.ux.desktop.App.

Updated 24.08.2016: Published smarter solution (see another answer by me).

于 2016-01-28T15:54:23.173 回答