Zugriff auf die übergeordnete Klasse in Backbone


69

Ich muss die initializeMethode der übergeordneten Klasse innerhalb der geerbten Klasse MyModelaufrufen, anstatt sie wie heute vollständig zu überschreiben.

Wie könnte ich das machen?

So sieht mein Code gerade aus:

BaseModel = Backbone.Model.extend({
    initialize: function(attributes, options) {
        // Do parent stuff stuff
    }
});

MyModel = BaseModel.extend({
    initialize: function() {
        // Invoke BaseModel.initialize();
        // Continue doing specific stuff for this child-class.
    },
});

Antworten:


52
MyModel = BaseModel.extend({
    initialize: function() {
        MyModel.__super__.initialize.apply(this, arguments);
        // Continue doing specific stuff for this child-class.
    },
});

1
@Industrial dann macht es etwas Dummes. Versuchen Siethis.__super__.initialize.apply(this, arguments);
Raynos

5
__ super __ist nicht dazu gedacht, es direkt zu verwenden, wie der unterstrichene Name impliziert.
Yury Tarabanko

5
@ Raynos: Warum nicht BaseModel.prototype.initialize.apply(this, arguments);? das sollte ohne funktionieren __super__.
Yury Tarabanko

6
documentcloud.github.com/backbone/#Model-extend Kurz beiseite zu Super: JavaScript bietet keine einfache Möglichkeit, Super aufzurufen - die Funktion mit demselben Namen, die weiter oben in der Prototypenkette definiert ist. Wenn Sie eine Kernfunktion wie set oder save überschreiben und die Implementierung des übergeordneten Objekts aufrufen möchten, müssen Sie sie explizit aufrufen ...
Yury Tarabanko

4
FWIW Jeremy Ashkenas gibt an, dass dies __super__nicht für die direkte Verwendung vorgesehen ist.
MikeSchinkel

130

Versuchen

MyModel = BaseModel.extend({
    initialize: function() {
        BaseModel.prototype.initialize.apply(this, arguments);
        // Continue doing specific stuff for this child-class.
    },
});

Dies scheint auch bei _.bindAll(this)Aufrufen zu funktionieren , die die __super__Eigenschaft des Konstruktors undefiniert machen.
Scott Weaver

1
Besser als die Verwendung __super__hat der Unterstrich ein privates Mitglied vorgeschlagen
Marcel Falliere


5

Ich denke es wäre

MyModel = BaseModel.extend({
    initialize: function() {
        this.constructor.__super__.initialize.call(this);
        // Continue doing specific stuff for this child-class.
    },
});

Es istthis.__super__.initialize.call(this);
Raynos

Beides this.__super__.prototype.initialize.call(this);und this.__super__.initialize.call(this);wirft this.__super__ is undefinedFirebug ein.
Industrial

Versuchen Sie this.constructor .__ super __. Initialize.call (this);
Wheresrhys

2
Ich wollte Argumente an die Initialisierungsfunktion übergeben, und dies ist die einzige Version, die für mich funktioniert hat. This.constructor .__ super __. Initialize.call (this, Argumente);
Khalid Dabjan

FWIW Jeremy Ashkenas gibt an, dass dies __super__nicht für die direkte Verwendung vorgesehen ist.
MikeSchinkel


2

Ähnlich wie @wheresrhys, aber ich würde apply anstelle von call verwenden, falls BaseModel.initialize Argumente erwartet. Ich versuche zu vermeiden, die Attributzuordnung zu verarbeiten, die bei der Initialisierung an ein Backbone-Modell übergeben werden kann. Wenn das BaseModel jedoch tatsächlich eine Ansicht oder eine Sammlung wäre, möchte ich möglicherweise Optionen festlegen.

var MyModel = BaseModel.extend({
    initialize: function() {
        this.constructor.__super__.initialize.apply(this, arguments);
        // Continue doing specific stuff for this child-class.
    },
});

FWIW Jeremy Ashkenas gibt an, dass dies __super__nicht für die direkte Verwendung vorgesehen ist.
MikeSchinkel

0

Hier ist eine CallSuper-Methode für mehrere Generationen. Fügen Sie sie einfach Ihrer erweiterten Klasse hinzu.

callSuper: function (methodName) {
    var previousSuperPrototype, fn, ret;

    if (this.currentSuperPrototype) {
        previousSuperPrototype = this.currentSuperPrototype;
        // Up we go
        this.currentSuperPrototype = this.currentSuperPrototype.constructor.__super__;
    } else {
        // First level, just to to the parent
        this.currentSuperPrototype = this.constructor.__super__;
        previousSuperPrototype = null;
    }

    fn = this.currentSuperPrototype[methodName];

    ret = (arguments.length > 1) ? fn.apply(this, Array.prototype.slice.call(arguments, 1)) : fn.call(this);

    this.currentSuperPrototype = previousSuperPrototype;

    return ret;
}

-4

Sie können Ihren Code mithilfe der funktionalen Vererbung neu schreiben.

var BackBone=function(){
    var that={};

    that.m1=function(){

   };
   return that;

};

var MyModel=function(){

 var that=BackBone();
 var original_m1=that.m1;

//overriding of m1
 that.m1=function(){
    //call original m1
 original_m1();
 //custom code for m1
  };
};

Ich bezweifle, dass das Umschreiben des Backbones hier in Ordnung ist :) Wir müssen mit der Struktur umgehen, die uns das Backbone gibt, und es gibt weitaus bessere Lösungen als das Umschreiben all dessen, als wäre das Super mehr als genug.
Sander
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.