3

In Marionette, how might I go about calling a function of the same name on the parent object of a view without overwriting the original function?

For instance:

var someView = new Backbone.Marionette.ItemView.extend({
    onRender: function () {
        console.log('foo');
    }
});

var anotherView = someView.extend({
    onRender: function () {

        // call someView's original onRender function

        console.log('bar');
    }
});

anotherView.render();

Resulting in the console output:

foo
bar
nimh
  • 33
  • 1
  • 5
  • 1
    So you don't mean the parent view (in the tree), but the `super` view from which you inherited? – Bergi Jun 04 '14 at 01:22

1 Answers1

7

You can use __super__, which is set up by extend:

var anotherView = someView.extend({
    onRender: function () {
        this.__super__.onRender.call(this);
        console.log('bar');
    }
});

or just directly reference the method that you want to apply on your instance:

var anotherView = someView.extend({
    onRender: function () {
        someView.prototype.onRender.call(this);
        console.log('bar');
    }
});

For more information, see Javascript Class Inheritance For Functions and what .call() does.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • This is precisely what I was looking for. Thank you. – nimh Jun 05 '14 at 06:23
  • upvote for your second example, in Marionette 2.0.0 at least the first example says undefined for super – Neil Jul 14 '17 at 14:44
  • Neither of these were working in Marionette 4.1.2. Had to use this: `Object.getPrototypeOf(this).onRender.call(this);` – Briguy37 Feb 15 '22 at 16:38
  • @Briguy37 What error are you getting on the second one? Despite this answer being 8 years old, `Superclass.prototype.method.call` is an ageless solution that also works with ES6 classes. Does Marionette no longer use standard prototype inheritance? – Bergi Feb 15 '22 at 17:37
  • @Bergi `this.prototype` was `undefined` when I debugged it as a watch in Chrome devtools, but the `[[Prototype]]` property was displayed on it, and accessible with the `Object.getPrototypeOf` from my previous comment. – Briguy37 Feb 15 '22 at 18:27
  • @Bergi Now that I look at it and re-read my comments, I'm wondering if maybe I tried `this.prototype` rather than the `someView.prototype` approach. – Briguy37 Feb 15 '22 at 18:30
  • @Briguy37 Yeah, `this.prototype` doesn't work, you need to use `someView.prototype`. I recommend to avoid `Object.getPrototypeOf(this)` since it doesn't work if you further inherit from the class. A better alternative (closer to what `super` does in ES6 classes) is `Object.getPrototypeOf(anotherView.prototype).onRender.call(this, …)`. – Bergi Feb 15 '22 at 18:54