LZX delegates only work with LZX events. Flash events require
closures. So you are getting tripped up trying to bridge the gap.
You'll have to use a closure to handle the flash event, and if you
want to handle the Flash event with an LZX method, you have to make
your own closure over `this`. If you poke around in the runtime, you
will see that the LFC does exactly this to trampoline most runtime
events out to LZX.
Clearly this could be improved. The same issue holds if you were
trying to handle a native browser event in the DHTML runtime and
bridge it to LZX.
[cc-ing laszlo-dev]
Maybe Delegates should be made smarter? Maybe they should notice
when the object they are trying to listen to is not an LZX event and
use the native runtime event handling mechanism?
On 2007-01-16, at 10:31 EST, Tyler Pitchford wrote:
Thanks for the excellent analysis, it appears I need to read more on
JS closures and their oddities. I do wonder, however, when I attempted
to utilize the LZX delegate system the event was never fired:
<handler name="oninit">
this._onSyncDel = new LzDelegate(this, "_onStatus", this._so,
"onSync");
</handler>
never called yourInstance's _onStatus method. Any suggestions on that?
Thanks again,
Tyler
On 1/16/07, P T Withington <[EMAIL PROTECTED]> wrote:
On 2007-01-16, at 00:13 EST, Tyler Pitchford wrote:
> When using an outside actionscript object (in this example a
> SharedObject) I'm getting some odd results when I try to attach
> handlers to events on the object.
>
> If I use the code:
For the purpose of exposition, I'll refer to the instance these
appear in as `yourInstance`.
> <event name="onSync"/>
> <handler name="oninit">
> var t = this;
Here you are creating your own closure over `this` (which is
`yourInstance`), so that calling the `onSync` method on the `_so`
object correctly calls the `_onStatus` method of `yourInstance`.
> this._so.onSync = function(evtObj) {
> t._onStatus(evtObj);
> };
> </handler>
>
> and in the attaching class:
>
> this._onSyncDel = new LzDelegate(this, "syncHandler", this._so,
> "onSync");
>
> everything works fine and this._so.onSync = an LzEvent object. If,
> however, I use this:
>
> <event name="onSync"/>
> <handler name="oninit">
Here, no closure is created. You are assigning the naked method
`_onStatus` to the `onSync` method of the `_so` object.
`yourInstance` is not captured. Inevitably, when `_so.onSync` is
invoked `this` in `_onStatus` is `_so`, not `yourInstance` as you
might have expected.
You could call this a bug in Javascript, since other languages
automatically close over `this` when capturing a method. This bug is
proposed to be fixed in Javascript 2, but in Javascript 1, you either
need to create your own closure, or you need to use the LZX delegate
system (which is really just a manual closure).
> this._so.onSync = this._onStatus;
> </handler>
>
> and
>
> the same in the attaching class this._so.onSync = a Function object
> pointing to the evet exposings _onStatus method. Then if I
change the
> code to:
>
> <event name="onSync"/>
> <handler name="oninit">
> this._onSyncDel = new LzDelegate(this, "_onStatus", this._so,
> "onSync");
> </handler>
>
> The event simply doesn't fire. While it took me awhile to figure
out
> the fix I demonstrated in the first example, shouldn't at least the
> first two function the same? It appears calling this._so.onSync =
> this._onStatus is actually overwriting this.onSync instead of
> this._so.onSync, any ideas?
>
> Cheers,
> Tyler