In-depth answer! You lost me at first with the explanation how the classes work etc, but after reading it two times and the combination with my "problem" I think it's clear :) I understand anyway why this.parent doesn't exists anymore.
The renaming of the parent method in the Init method of a class is a quick way to get around it, indeed it feels hacky.. I will not use it (also, because you say it's hacky, if I came up with the idea I might have thought it was a smart hack, hehehe). I will probably just copy the parent's method, leave 80% of it like it is and add what I need. Done. Thanks! On Jan 5, 10:37 pm, Aaron Newton <[email protected]> wrote: > You are delving into the depths of how Class works, so this is going to get > a little complicated. > > All methods of classes are wrapped in a function that then calls the > function in question. So if you pass an object to Class that has a > *foo* method, > Class returns a constructor that when invoked returns an object that has a * > foo* method that calls the original one. > > var fooBase = { > foo: function(){ alert('foo'); }}; > > var Foo = new Class(fooBase); > var myFoo = new Foo(); > myFoo.foo(); //alerts "foo" > > When we call the *foo* method on our instance, we're really calling the > wrapper that the Class constructor put around the *foo* method on our > fooBase object. This wrapper therefore knows when *foo* is being called, and > before it calls the original *foo* it defines *this.parent*. It doesn't look > like this, but here's a very simple illustration: > > instanceOfFoo.foo = function(){ > this.someVar = 'blah'; > this.originalFooMethod(); > delete this.someVar; > > }; > > So only while our original method is being run is *this.parent* defined (and > only if there is a parent method on the prototype). > > If you think about it, that's the only way this could work, because * > this.parent *has to point at different things depending on which method is > calling it. *this* is our instance, and the *parent* property of our > instance changes depending on the method. Removing it after a method is > called is the only way to allow the next method to call it. > > So, let's look at your code: > > showMask: function() { > var fn = function() { > this.parent(); > }.bind(this); > this.element.tween('opacity', this.options.opacity).get('tween').chain( > fn); > }, > > Your method calls *element.tween*, which starts an effect. After the effect > it calls your function, which references *this.parent*. But this > asynchronous method call is going to occur *after* the *showMask* method > exits, which means that *this.parent *has been deleted, right? > > So, how do you extend a class and add this kind of effect? The only > mechanism to do this is to rename the original methods: > > var Foo.Extended = new Class({ > Extends: Foo, > initialize: function(){ > this._foo = this.foo; > this.foo = this._newFoo; > }, > _newFoo: function(){ > (function(){ > this.parent(); > }).delay(1000, this); > }}); > > var myFoo = new Foo.Extended(); > myFoo.foo(); //waits 1 second, alert's "foo" > > This is hacky and in general a bad practice. > > If you look at the showMask method in Spinner, which completely overwrites > the method from Mask (it does not call this.parent), you can see how it does > this fading in. Note that I *could* have done this method renaming from the > example above, but that method renaming is more brittle than I prefer. I've > only used the technique on a very few occasions. > > > > On Tue, Jan 5, 2010 at 11:55 AM, Rolf -nl <[email protected]> wrote: > > I've extended more's Mask so I can apply an opacity tween effect to > > the mask... (and still have all the benefits of Mask, else I could use > > DWalsh's Overlay...) > > > Earlier I tried a simple way to extend Mask, just changing the > > showMask and hideMask methods: > >http://mootools.net/shell/A65x7/ > > > But then I get the error: The method "parent" cannot be called. > > Q1. Why can't I call the this.parent() methods showMask and hideMask? > > > Then I extended it in another way (needed to use it, so, went for the > > easy way out): > >http://mootools.net/shell/PMpZM/ > > > In the original Mask show (and hide) methods it says: > > this.showMask.apply(this, arguments); > > > Q2: When are these methods (show/hide) getting any arguments?
