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?

Reply via email to