My personal favorite is the use of the Delegate loaded with arguments.
//
// INTERACTION
//
function button_onPress ( btn:MovieClip )
{
var data = dataArray [ btn.id ];
var func = this [ 'func_' + data.section ];
func ( data );
}
//
// EVENTS
//
function func_work ( data:Object ) { trace( data.btn ); }
function func_portfolio ( data:Object ) { trace( data.id ); }
function func_about ( data:Object ) { trace( data.section ); }
//
// UTILS
//
function proxyBEFORE (s:Object, func:Function):Function
{
// from jgDelegate.as
var a:Array = arguments.slice(2, arguments.length);
return function ():Void { func.apply(s, a.concat(arguments)); };
}
//
// INIT
//
var dataArray = [ {section:'work'}, {section:'portfolio'}, {section:'about'}
];
var len = dataArray.length;
for ( var i = 0; i<len; i++)
{
var btn = holder [ 'btn_' + dataArray [i].section ];
dataArray[i].id = btn.id = i;
dataArray[i].btn = btn;
btn.onPress = proxyBEFORE ( this, button_onPress, btn );
}
_____________________________
Jesse Graupmann
www.jessegraupmann.com
www.justgooddesign.com/blog/
_____________________________
-----Original Message-----
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Alistair
Colling
Sent: Friday, May 04, 2007 8:59 AM
To: [email protected]
Subject: Re: [Flashcoders] Syntax for dynamically calling a function
Wow, thanks for all your suggestions guys, Lists, I really appreciate
the time you took to write your detailed response, I like your third
option the best. David thanks for your suggestion I am going to do
some further experimentation. I'll also have a look into the Event
Dispatcher class as this looks interesting but I'm not sure what
specific benefits it brings me here, I will do more research to find
out. For the moment I think I will stick with putting this code
inside my movie clip, and the do_ functions on the main timeline:
////
this.onPress = function(){
this._parent["do_" + this._name].call();
}
//
Thanks again everyone :)
On 3 May 2007, at 17:59, Lists wrote:
> The short answer is, you can invoke the function directly by writing:
>
> this.onPress = function () {
> _parent[this._name]();
> }
>
> or, if this looks clearer, you can use the call() method
>
> this.onPress = function () {
> _parent[this._name].call();
> }
>
> However, there are a few issues with this approach.
>
> First, I don't like the fact that there are two things with the
> same name in
> the same scope: a function and a movie clip. This might just be me
> being
> picky, but I'll show you an example of where this breaks in a moment.
>
> Second, it's not best practice to put scripts inside movie clips. It's
> easier to assign these functions from the main timeline.
>
> Third, I'm not sure what this gains you. It's easier to copy and
> paste but,
> if you're already going into the movie clip manually, you might as
> well just
> type the function name. Maybe if you reused the clip from movie to
> movie
> this step would already be done and you'd only have to write the
> function...
> Or maybe I'm missing another time saving purpose.
>
> Combining all three of the above issues, you can automatically assign
> functions to all your movie clips from the the main timeline by
> writing
> this:
>
> (assumes mcs on stage named "pictures", "help", and "home", and
> gets around
> same-name-in-same-scope by adding a "do_" prefix to the function name)
>
> //
> for (var s:String in this) {
> if (typeof(this[s]) == "movieclip") {
> this[x].onPress = function () {
> this._parent["do_" + this._name].call();
> }
> }
> }
> function do_pictures() {
> trace("pictures");
> }
> function do_help() {
> trace("help");
> }
> function do_home() {
> trace("home");
> }
> //
>
> This will cause EVERY mc in the main timeline to behave this way,
> so this
> approach may not be what you want, but it's a proof of concept. You
> could do
> this through an array of all mcs you want the function assigned to,
> or even
> do it manually like this:
>
> pictures.onPress = function () {
> this._parent["do_" + this._name].call();
> }
>
> But, again, without some sort of automation in applying the script,
> you lose
> the benefit. You might as well just write:
>
> pictures.onPress = function () {
> do_pictures();
> }
>
> If you want to see an example of the same-name-in-same-scope
> problem, run
> the first example above after removing "do_" from everything. The
> script
> will "work" but when it goes through and assigns the onPress event
> handler,
> it will assign it to the function pictures rather than the mc
> pictures. The
> function is seen before the mc in the execution order of the loop.
>
> Finally, if the lowercase string "movieclip" for typeof is
> confusing, you
> can substitute:
>
> if (this[x] instanceof MovieClip) {
_______________________________________________
[email protected]
To change your subscription options or search the archive:
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
Brought to you by Fig Leaf Software
Premier Authorized Adobe Consulting and Training
http://www.figleaf.com
http://training.figleaf.com