17

I have a few months of experience developing Extjs web application. I ran into this problem:

When I override a class, I modified the method and followed the previous implementation and invoke callParent(). The overriding part works but the callParent() invoked the old implementation.

my overriding code

Ext.override(Ext.layout.component.Draw, {
    finishedLayout: function (ownerContext) {

        console.log("new layouter being overriden");
        this.callParent(arguments);
    }
});

The Extjs class method to be overridden:

finishedLayout: function (ownerContext) {
    var props = ownerContext.props,
        paddingInfo = ownerContext.getPaddingInfo();

    console.log("old layouter being overriden");
    this.owner.setSurfaceSize(props.contentWidth - paddingInfo.width, props.contentHeight - paddingInfo.height);

    this.callParent(arguments);
}

In the console, I can see that first the new layouter prints out the message followed by the old layouter implementation... I put a breakpoint and retrace the invocation stack, the callParent() of the new layouter called the old one. I need to call the parent class, but not the overridden method.

Any idea how to solve this problem?

MarthyM
  • 1,839
  • 2
  • 21
  • 23
Seng Zhe
  • 613
  • 1
  • 11
  • 21
  • Sorry to left out the version that I used, I am using ExtJs 4.1.2. The chosen answer is the correct approach but I could not use it, instead I used the answer provided by @wantok. – Seng Zhe Apr 10 '13 at 01:56
  • By the way, bypassing one of your supers is a big hack, use it wisely and sparingly! – Ruan Mendes Sep 20 '13 at 18:27

2 Answers2

21

If you're using ExtJS 4.1.3 or later you can use this.callSuper(arguments) to "skip" the overridden method and call the superclass implementation.

The ExtJS documentation for the method provides this example:

Ext.define('Ext.some.Class', {
    method: function () {
        console.log('Good');
    }
});

Ext.define('Ext.some.DerivedClass', {
    method: function () {
        console.log('Bad');

        // ... logic but with a bug ...

        this.callParent();
    }
});

Ext.define('App.patches.DerivedClass', {
    override: 'Ext.some.DerivedClass',

    method: function () {
        console.log('Fixed');

        // ... logic but with bug fixed ...

        this.callSuper();
    }
});

And comments:

The patch method cannot use callParent to call the superclass method since that would call the overridden method containing the bug. In other words, the above patch would only produce "Fixed" then "Good" in the console log, whereas, using callParent would produce "Fixed" then "Bad" then "Good"

Lorenz Meyer
  • 19,166
  • 22
  • 75
  • 121
hopper
  • 13,060
  • 7
  • 49
  • 53
  • Warning thought, in the third example, when using 'override' sometimes `this.callSuper();` will trigger errors in console. If this happens to you, you should try `this.callOverridden(arguments);` instead. [related thread](https://www.sencha.com/forum/showthread.php?173374-Ext-override()-on-Ext-components-in-ExtJS-4-x) – Olympiloutre Apr 11 '18 at 11:20
6

You can't use callParent but you can just call the grandparent class method directly instead.

GrandparentClass.prototype.finishedLayout.apply(this, arguments);

Here's a more generic (if somewhat fragile) approach.

this.superclass.superclass[arguments.callee.$name].apply(this, arguments);
wantok
  • 977
  • 5
  • 16
  • I think this is clearer since it shows your intention. Specially since skipping the overridden method seems like a hack – Ruan Mendes Sep 20 '13 at 18:25