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?
>

Reply via email to