Hey Rolf, I modified your example to work without having to do any renaming, and still keep all of the logic in the See the 'hide' method.
http://mootools.net/shell/JfhBn/1/ --Perrin On Thu, Jan 7, 2010 at 3:16 PM, Rolf -nl <[email protected]> wrote: > 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? >
