Показать сообщение отдельно
Старый 08.11.2006, 16:32
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 99  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
По умолчанию 93. Proxy: методы перечисления (nextName(), nextValue(), nextNameIndex())

Помимо создания динамических свойств и методов в Proxy (flash.utils.Proxy) есть возможность управлять порядком перечисления свойств в циклах for..in и for each..in. Для этого используются методы класса:
  • nextName(index:int):String
  • nextValue(index:int):*
  • nextNameIndex(index:int):int
Метод nextName возвращает название свойства по порядковому номеру для цикла for..in (аналогично nextValue для цикла for each..in). nextNameIndex вызывается перед началом каждой итерации в цикле и отвечает за две вещи:
1) предоставляет порядковый номер для nextName и nextValue (если возвращаемое значение >0), или
2) прерывает цикл (если возвращаемое значение равно нулю).
При начале цикла nextNameIndex получает порядковый номер равный нулю. Каждое последующее значение возвращаемое nextNameIndex отлично от нуля и передается методам nextName и nextValue. Если nextNameIndex возвращает ноль, то цикл заканчивается.
К примеру, proxy имеет 3 свойства (x,y,visible), попробуем их перечислить в цикле for..in
Код:
for (var prop:String in proxy) {
    trace(prop);
}
Здесь будут вызываться методы nextNameIndex и nextName:
Код:
for (var prop:String in proxy) {
	[ proxy.nextNameIndex(0) -> return 1 ]
	[ proxy.nextName(1) -> return "x" ]
	[ prop = "x" ]
	trace(prop); // x
	(end for block, repeat)
	[ proxy.nextNameIndex(1) -> return 2 ]
	[ proxy.nextName(2) -> return "y" ]
	[ prop = "y" ]
	trace(prop); // y
	(end for block, repeat)
	[ proxy.nextNameIndex(2) -> return 3 ]
	[ proxy.nextName(3) -> return "visible" ]
	[ prop = "visible" ]
	trace(prop); // visible
	[ proxy.nextNameIndex(3) -> return 0 ]
	(0 index, break from for block)
}
Если использовать цикл for each..in, то nextValue будет вызываться вместо nextName.
Поскольку в циклах используется порядковый номер, то удобно хранить динамические свойства в массиве и в методах nextName или nextValue просто вернуть элемент массива index-1 (поскольку nextName и nextValue никогда не получают порядкового номера 0).
Создадим прокси-класс, который реализует пример выше. Помните, что методы proxy определены в пространстве имен flash_proxy.
Код:
package {
    
    import flash.utils.Proxy;
    import flash.utils.flash_proxy;
    
    public class ProxyEnum extends Proxy {
        
        private var props:Array = ["x", "y", "visible"]; // массив свойств
        
        // nextNameIndex вызывается при начале итерации в цикле
        override flash_proxy function nextNameIndex (index:int):int {
            if (index < props.length) {
                // первый вызов 0, возвращаем 1 + index
                // т.е. порядковый номер будет 1, затем 2, 3
                return index + 1;
            } else {
                // все свойства перечислены для прерывания цикла
                // возвращаем 0
                return 0;
            }
        }
        
        // nextName вызывается после nextNameIndex и порядковый номер начинается с 1
        override flash_proxy function nextName(index:int):String {
            // возвращаем элемент массива index – 1
            return props[index - 1];
        }
    }
}
Пример использования:
Код:
var proxy:ProxyEnum = new ProxyEnum();
for (var prop in proxy) {
    trace(prop);
}
/* output:
x
y
visible
*/
Для полной картины необходимо еще переопределить методы nextValue и getProperty. Но для них нужны возвращаемые значения, пусть класс принимает в конструкторе ссылку на какой-то отображаемый объект, его свойства и будем возвращать.
Код:
package {
    
    import flash.display.DisplayObject;
    import flash.utils.Proxy;
    import flash.utils.flash_proxy;
    
    public class ProxyEnum extends Proxy {
        
        private var props:Array = ["x", "y", "visible"]; // массив свойств
        private var _target:DisplayObject;
        
        function ProxyEnum(target:DisplayObject) {
            _target = target;
        }
        
        // nextNameIndex вызывается при начале итерации в цикле
        override flash_proxy function nextNameIndex (index:int):int {
            if (index < props.length) {
                // первый вызов 0, возвращаем 1 + index
                // т.е. порядковый номер будет 1, затем 2, 3
                return index + 1;
            } else {
                // все свойства перечислены для прерывания цикла
                // возвращаем 0
                return 0;
            }
        }
        
        // nextName вызывается после nextNameIndex и порядковый номер начинается с 1
        override flash_proxy function nextName(index:int):String {
            // возвращаем элемент массива index – 1
            return props[index - 1];
        }
        
        // nextValue вызывается после nextNameIndex в циклах for each..in
        override flash_proxy function nextValue(index:int):* {
            // получаем название свойства из массива
            var prop:String = props[index - 1];
            // и возвращаем его значение
            return _target[prop];
        }
        
        // возвращает значение свойства по его имени
        override flash_proxy function getProperty(name:*):* {
            return _target[name];
        }
    }
}
Пример использования:
Код:
var proxy:ProxyEnum = new ProxyEnum(my_mc);

for (var prop:String in proxy) { // nextName/nextNameIndex
    trace(prop);
    trace(proxy[prop]); // getProperty
}
/* output:
x
34
y
76
visible
true
*/

for each(var value:* in proxy) { // nextValue/nextNameIndex
    trace(value);
}
/* output:
34
76
true
*/
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.