2016-08-02 1 views
0

Mon but est d'avoir un objet widget et d'avoir des widgets spécifiques pour étendre cet objet. Je voudrais empêcher les gens d'avoir à appeler le callback explicitement dans chaque définition de widget en l'étendant en quelque sorte dans le parent (Widget). Quelle est la meilleure façon d'y parvenir?Javascript "extension" d'une méthode dans un sous-objet ou une sous-classe

var Widget = function (options) { 

    // super class 

    if (this.constructor === Widget) { 
     throw new Error("You can't instantiate abstract class."); 
    } 

    var widget = this.__proto__; 

    Widget.renderCallBack = function(){ 
     //alert('the widget has rendered'); 
    } 

    this.render = (function(){ 
     var _render = this.render; 

     return function(){ 
      _render(); 
      Widget.renderCallBack(); 
     } 

    }) 


} 
Widget.constructor = Widget; 


var SpecialWidget = function(options) { 
    Widget.apply(this, arguments); 
} 

SpecialWidget.prototype = Object.create(Widget); 
SpecialWidget.constructor = SpecialWidget 

SpecialWidget.prototype.render = function(){ 
    // render something 
} 

new SpecialWidget(options); 
+0

je passerais dans le renderCallback en option pour SpecialWidget et mettez-est de rendre la méthode de l'appeler. __var sw = new SpecialWidget ({renderCallback: function() {}}); __ – cstuncsik

+0

Cela fonctionnerait mais j'essaye d'abstraire ce "callback" dans l'objet Widget car je veux que tous les "widgets spéciaux" aient une fonction de rendu , et je veux que la même chose se produise après que chaque fonction de rendu s'exécute sans devoir coder explicitement cela dans chacun. Est-ce possible/une bonne idée? –

Répondre

0

En plus de mon commentaire: Si c'est le même pour tous, il ne doit pas être une fonction de rappel, il suffit de mettre le code à la fin de la méthode render si son emploi est synchrone, sinon utilisez une promesse, mais vous devez penser à celle de l'ombrage de la méthode, vous écraserez la méthode render de la classe parent dans l'enfant. Pour éviter cela, vous pouvez utiliser un nom différent pour les méthodes et appeler la méthode parent de l'enfant ou utiliser la classe ES2015 qui a le mot-clé super pour atteindre les méthodes de la classe parente.

aussi vous avez eu une faute de frappe dans votre code:

SpecialWidget.prototype = Object.create(Widget); 

Il doit être:

SpecialWidget.prototype = Object.create(Widget.prototype); 

Quoi qu'il en soit, je ne pense pas que ce soit une bonne idée en général.

var Widget = function(options) { 
 
    this.options = options || {}; 
 
}; 
 

 
Widget.prototype.widgetRender = function() { 
 
    // do stuff 
 
    console.log('Widget render'); 
 
    // callback functionality 
 
    console.log('Widget render callback functionality'); 
 
}; 
 
Widget.constructor = Widget; 
 

 

 
var SpecialWidget = function(options) { 
 
    Widget.apply(this, arguments); 
 
}; 
 

 
SpecialWidget.prototype = Object.create(Widget.prototype); 
 
SpecialWidget.prototype.render = function() { 
 
    // parent's render 
 
    this.widgetRender(); 
 
    // do stuff 
 
    console.log('SpecialWidget render'); 
 
    // callback functionality 
 
    console.log('SpecialWidget render callback functionality'); 
 
}; 
 
SpecialWidget.constructor = SpecialWidget 
 

 
var sw = new SpecialWidget(); 
 
sw.render(); 
 

 
// ES2015 
 

 
class ES6Widget { 
 
    constructor(options) { 
 
    this.options = options || {}; 
 
    } 
 
    render() { 
 
    // do stuff 
 
    console.log('ES6Widget render'); 
 
    // callback functionality 
 
    console.log('ES6Widget render callback functionality'); 
 
    } 
 
} 
 

 
class ES6SpecialWidget extends ES6Widget { 
 
    render() { 
 
    // parent's render 
 
    super.render(); 
 
    // do stuff 
 
    console.log('ES6SpecialWidget render'); 
 
    // callback functionality 
 
    console.log('ES6SpecialWidget render callback functionality'); 
 
    } 
 
} 
 

 

 
const es6sw = new ES6SpecialWidget(); 
 
es6sw.render();