вторник, 12 июля 2011 г.

Exploring Flex Proxy class


Proxy is a rather interesting class. It gives you an opportunity to override basic behaviour of some actionscript 3 operators (such as "for each...in", "for...in", "delete", "[]"). You cannot create Proxy instances directly, you must override it and override needed methods.
Proxy is a good class to build enumerable collections. Let's create a custom collection, which overrides Proxy and implements some its basic behaviour.
First I'm going to implement enumeration logic. There are 3 methods in Proxy class, which will help us:

nextNameIndex(index : int) : int
nextName(index : int) : String
nextValue(index : int) : *

nextNameIndex is called within each iteration in "for each...in" and "for...in" loops. It receives index, which is being incremented every iteration by 1 (starting with 0). In this method you're supposed to return an int, which will be next passed to nextValue ("for each...in") or nextName ("for...in"). An important moment here: you return 0 to stop the loop.

There'll be an array as the source of our collection.


flash_proxy override function nextNameIndex(index : int) : int
{
 return index < source.length ? index + 1 : 0;
}
 
flash_proxy override function nextName(index : int) : String
{
 return (index - 1).toString();
}
 
flash_proxy override function nextValue(index : int) : *
{
 return source[index - 1];
}


Pay attention, that all methods are declared in flash_proxy namespace, so don't forget to add  "use namespace flash_proxy" before class declaration.
As you see, we return (index + 1) in  "nextNameIndex", because we cannot return 0 as index. But we use (index - 1) in "nextName" and "nextValue".

To override "[]" operator we should implement "getProperty" and "setProperty" methods.


flash_proxy override function getProperty(name : *) : *
{
 if (name is String && !isNaN(parseInt(name)))
  return source[int(parseInt(name))];
 else
  return undefined;
}
 flash_proxy override function setProperty(name : *, value : *) : void
{
 if (name is String && !isNaN(parseInt(name)))
  source[int(parseInt(name))] = value;
 else
  throw new Error("Illegal index");
}


Using our class:

var col : CustomCollection = new CustomCollection();
for (var i : int = 0; i < 3; i++)
 col[i] = i.toString() + "str";
trace("For each loop:");
for each (var elem : * in col)
 trace(elem);
trace("For loop:");
for (var key : String in col)
 trace("Key: " + key + ", value: " + col[key]);


 More info about Proxy class you can find here.

Комментариев нет:

Отправить комментарий