Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reuse and override inherited javascript function

I have a class for mouse events. I'm using dojo b/c I like its OO approach

dojo.declare("MouseObject", null, {
  constructor: function(){},
  onclick : function(){...},
  _onClick : function(){...}
});

_onClick() listens for window generated mouse press/release events and determines if a click has occurred. If it has, onClick() is called. onClick() carries out functionality common to all possible clicks, so it needs to be called every time the user clicks.

sometimes the user may want to extend the functionality of onClick() Is there anyway to incorporate the original functionality without copy pasting it? Two ways I can think of, neither of which I like, are

dojo.declare("MouseObjectChild", [MouseObject], {
  constructor: function(){},
  onclick : function(){this.inherited(arguments);...}
});

which has the drawback that I have to keep creating new classes I don't really need, and two adding an intermediate function

dojo.declare("MouseObject", null, {
      constructor: function(){},
      onclick : function(){this._onClick()...}, //child onClick
      _onClick : function(){...}, //parent onClick
      __onClick : function(){...} //listener
    });

but this does not look like good code


wrt the bounty, I want expert advice on how best to address the program-user interaction. If the program provides a crucial function, such as draw a circle on the canvas, then how does the user best interact with that. What if the user wants to draw a triangle behind the circle? A square in front of the circle? Then the program would have to provide pre and post methods like so:

beforeDraw();
draw();
afterDraw();

Is this considered good design? Should I instead put function pointers in an array and call them in order?

like image 205
puk Avatar asked Oct 11 '22 21:10

puk


1 Answers

As suggested by the "should I put functions in their own array and call them in order" and "build your own event system" ideas, you might want to have a look at the dojox.lang.aspect library that comes bundled in the extended standard library. It should be basically a more advanced version of the "dojo.connect" solution.

dojo.require('dojox.lang.aspect');
var aop = dojox.lang.aspect;

function log(msg){ return function(){
    console.log(msg);
};}

var obj = {
   draw : log('draw circle');
};

obj.foo();
//prints
//  draw circle

aop.advise(obj, 'draw', [
    {before: log('draw triangle')},
    {after: log('draw a square')},
    {after: log('done!')}
]);

obj.foo();
//prints
//  draw a triangle
//  draw a circle
//  draw a square
//  done!
like image 125
hugomg Avatar answered Oct 14 '22 04:10

hugomg