On Jan 17, 2008 12:57 AM, applecoremilo <[EMAIL PROTECTED]> wrote:
> heres some example code
>
> for(var i = 0; i < 16;i++)
> {
> var foo:extendedCanvasObj = new extendedCanvasObj();
>
> foo.setstyle.......
>
> foo.addEventListener(dragEvent.DRAG_ENTER,function
> (event:DragEvent) {change the canvas backgroundcolour };
>
> container.addChild(foo);
> }
You left out the actual code that is causing the problem - it sounds
like you've created an anonymous function inside the loop (to change
the canvas background color).
Although ActionScript3 syntax appears to support nested scopes for
variables by allowing you to declare a variable anywhere (such as
inside a for loop), in actuality all variables are scoped to the
function in which they are defined. Therefore, even though it looks
like you've defined "foo" 16 separate times (and that "foo" goes out
of scope at the end of the loop), the compiler rewrites the function
slightly to look more like this:
var foo:extendedCanvasObj = new extendedCanvasObj();
for(var i = 0; i < 16;i++)
{
foo.setstyle.......
foo.addEventListener(dragEvent.DRAG_ENTER,function
(event:DragEvent) {change the canvas backgroundcolour };
container.addChild(foo);
}
If you are creating an anonymous function and assigning it as the
event listener on foo in every loop, you might think that you are
creating a closure to capture the state of the variable "foo" at the
time that you define the function (i.e., making a copy of "foo" for
each iteration of the loop). However, what is *really* happening is
you are simply closing over a reference to "foo", so that at some
future time when the anonymous function (the event handler) is
invoked, it looks up the value of "foo" *at the time the function is
invoked*. Since "foo" is now equal to the last value of the item in
the loop (remember, "foo" does not go out of scope at the end of each
iteration), the anonymous function that is acting as your event
handler will always act upon the object that "foo" last pointed to.
The workaround is to create a helper function, defined outside of the
function in which you are doing all of this, to which you pass "foo"
and which returns function objects that you can then assign as event
handlers. The reason this works is because you create an entirely new
scope each time the helper function is invoked (which is similar to
the effect you are trying to achieve by declaring your "foo" variable
inside the for loop).
An extremely simplified and untested example - this might not actually
work but it gives you the right idea:
function assignEventHandlers():void
{
// declare 'foo' out here to help clarify that it is
// function-scoped, not loop iteration-scoped.
var foo:extendedCanvasObj;
for (var i:int = 0; i < 16; i++)
{
foo = new extendedCanvasObj();
var handler:Function = createBgColorChangeHandler(foo);
foo.addEventListener(DragEvent.DRAG_ENTER, handler);
}
}
// the "helper" - helps by creating a new scope
function createBgColorChangeHandler(obj:Object):Function
{
return function(event:DragEvent)
{
// do whatever you need to do here
obj.backgroundColor = "red";
};
}
Hope that helps,
e