Backbone.js affiche l’inheritance

J’ai une vue appelée Pannel qui est juste un fond avec un bouton de fermeture. Je veux étendre cette vue à celle appelée PannelAdvanced . Comment ferais-je cela avec backbone.js?

À l’heure actuelle, tous les exemples ont Backbone.View.Extend mais ceux-ci ne font que prolonger Backbone.View ; Je veux étendre mon PannelView .

La manière la plus simple d’hériter une vue est de faire ce que d’autres personnes ont déjà suggéré dans les commentaires:

 var Pannel = Backbone.View.extend({ }); var PannelAdvanced = Pannel.extend({ }); 

Mais comme vous l’avez noté dans vos commentaires, si vous avez une méthode d’initialisation dans Pannel, elle ne sera pas appelée si vous avez également une méthode d’initialisation dans PannelAdvanced, vous devez donc appeler explicitement la méthode d’initialisation de Pannel:

 var Pannel = Backbone.View.extend({ initialize: function(options){ console.log('Pannel initialized'); this.foo = 'bar'; } }); var PannelAdvanced = Pannel.extend({ initialize: function(options){ Pannel.prototype.initialize.apply(this, [options]) console.log('PannelAdvanced initialized'); console.log(this.foo); // Log: bar } }); 

C’est un peu moche parce que si vous avez beaucoup de Views qui héritent de Pannel, vous devrez vous rappeler d’appeler l’initialisation de Pannel à partir de toutes. Pire encore, si Pannel n’a pas de méthode d’initialisation maintenant, mais que vous choisissez de l’append ultérieurement, vous devrez ensuite accéder à toutes les classes héritées et vous assurer qu’elles appellent l’initialisation de Pannel. Voici donc une autre façon de définir Pannel afin que vos vues héritées n’aient pas besoin d’appeler la méthode d’initialisation de Pannel:

 var Pannel = function (options) { // put all of Panel's initialization code here console.log('Pannel initialized'); this.foo = 'bar'; Backbone.View.apply(this, [options]); }; _.extend(Pannel.prototype, Backbone.View.prototype, { // put all of Panel's methods here. For example: sayHi: function () { console.log('hello from Pannel'); } }); Pannel.extend = Backbone.View.extend; // other classes inherit from Panel like this: var PannelAdvanced = Pannel.extend({ initialize: function (options) { console.log('PannelAdvanced initialized'); console.log(this.foo); } }); var pannelAdvanced = new PannelAdvanced(); //Log: Pannel initialized, PannelAdvanced initialized, bar pannelAdvanced.sayHi(); // Log: hello from Pannel 

C’est l’une des raisons pour lesquelles j’aime tant utiliser Coffeescript. Des choses comme l’inheritance sont tellement mieux. Pour relier la réponse correcte de JohnnyO, je peux dire la même chose dans Coffeescript:

 class Panel extends Backbone.View initialize: -> console.log 'Panel initialized' @foo = 'bar' class PanelAdvanced extends Panel initialize: -> super console.log 'PanelAdvanced initialized' console.log @foo 

Pour aller un peu plus loin:

J’ai aimé l’approche de @ JohnnyO mais je voulais confirmer qu’une vue résultante était toujours capable de faire tout ce qu’elle était censée faire. Compte tenu de son approche, je ne pensais pas qu’il y aurait des problèmes, mais je voulais être un peu plus certain.

J’ai donc pris une minute et adapté la suite de tests Backbone.js Views à la technique d’inheritance multiple proposée par @JohnnyO.

Vous pouvez exécuter les résultats sur http://jsfiddle.net/dimadima/nPWuG/ . Tous les tests réussissent

Ma base et mes vues étendues:

 var RegularView = function (options) { // All of this code is common to both a `RegularView` and `SuperView` // being constructed. this.color = options && (options.color || 'Green'); // If execution arrives here from the construction of // a `SuperView`, `Backbone.View` will call `initialize` // that belongs to `SuperView`. This happens because here // `this` is `SuperView`, and `Backbone.View`, applied with // the current `this` calls `this.initialize.apply(this, arguments)` Backbone.View.apply(this, arguments) }; RegularView.extend = Backbone.View.extend; _.extend(RegularView.prototype, Backbone.View.prototype, { // Called if a `RegularView` is constructed`, // Not called if a `SuperView` is constructed. initialize: function () { console.log('RegularView initialized.'); }, say_hi: function() { console.log('Regular hi!'); } }); var SuperView = RegularView.extend({ // Called if a `SuperView` is constructed`, // Not called if a `RegularView` is constructed. initialize: function(options) { console.log('SuperView initialized.') }, say_hi: function() { console.log('Super hi!'); } }) 

Pour la suite de tests, j’ai récupéré les derniers tests de vues de GitHub et remplacé les occurrences de Backbone.View par RegularView . Les tests utilisent ensuite RegularView et les résultats de RegularView.extend() pour s’assurer que les deux font ce qu’ils sont censés faire.