Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Как получить переменную внутри функции обработчика события? (http://www.flasher.ru/forum/showthread.php?t=127225)

vvvvvvf 08.07.2009 14:07

Как получить переменную внутри функции обработчика события?
 
Доброго времени суток.
Столкнулся с такой проблемой, мне нужно реализовать определенное количество контейнеров (количество контейнеров получаю с сервера), и к каждому контейнеру нужно прицепить свой Timer. Чтобы реализовать это я создаю массив Timer-ов и каждый Timer в функции обработчике должен знать свой индекс.

Тут такая проблема как получить свой i в функции обработчике?
в данном коде всегда возвращается 10 и это понятно, а как сделать чтобы возвращался свой i, то есть 1, 2, 3 и т.д?

Код #1
Код AS3:

package {
        import flash.display.*;
        import flash.events.*;
        import flash.utils.*;
 
        public class myClass extends Sprite {
                private var myTimer:Array = new Array();
 
                public function myClass():void {
                        for (var i:int = 0; i < 10; i++) {
                                myTimer[i] = new Timer(1000);
                                myTimer[i].start();
                                myTimer[i].addEventListener(TimerEvent.TIMER, function (e:*) {
                                        trace('Как тут получить доступ к своей переменной i?');
                                        trace('i:'+i); // во всех 10 обработчиках, выдает 10
                                });
                        }
                }
        }
}

или такой более правильный код, как тут получить у каждого свой i?

Код #2
Код AS3:

package {
        import flash.display.*;
        import flash.events.*;
        import flash.utils.*;
 
        public class myClass extends Sprite {
                private var myTimer:Array = new Array();
 
                public function myClass():void {
                        for (var i:int = 0; i < 10; i++) {
                                myTimer[i] = new Timer(1000);
                                myTimer[i].start();
                                myTimer[i].addEventListener(TimerEvent.TIMER, doTime);
                        }
                }
                public function doTime(e:TimerEvent):void {
                        trace('Как тут получить доступ к своей переменной i?');
                        trace('i:'+i);
                }
        }
}



или вопрос можно поставить так: Как расширить экземпляр myTimer[i] и добавить в него например свойство id, чтобы выглядело так?

Код #3
Код AS3:

package {
        import flash.display.*;
        import flash.events.*;
        import flash.utils.*;
 
        public class myClass extends Sprite {
                private var myTimer:Array = new Array();
 
                public function myClass():void {
                        for (var i:int = 0; i < 10; i++) {
                                myTimer[i] = new Timer(1000);
                                // каким-то чудесным способом мы
                                // тут добовляем экземпляру
                                // новое свойство id
                                myTimer[i].id;
                                // а тут уже присваиваем этому
                                // свойству само значения переменной i
                                myTimer[i].id = i;
                                myTimer[i].start();
                                myTimer[i].addEventListener(TimerEvent.TIMER, doTime);
                        }
                }
                public function doTime(e:TimerEvent):void {
                        // а в самой функции обработчеке мы уже
                        // достаем это свойство id и
                        // присваиваем его к переменной i
                        var i:Number = e.currentTarget.id;
                        trace('i:'+i);
                }
        }
}

И еще раз повторю вопрос для тех кто ничего не понял:
Как расширить экземпляр myTimer[i] и добавить в него свойство id?

Gal4enochek 08.07.2009 14:18

Например так
Код AS3:

package utils
{
        import flash.utils.Timer;
 
        public class MyTimer extends Timer
        {
                public var id :int;
 
                public function MyTimer(delay:Number, id:int, repeatCount:int=0)
                {
                        super(delay, repeatCount);
                        this.id = id;
                }
 
        }
}

и вызов
Код AS3:

        for (var i : int = 0; i<5; i++){
                var t :MyTimer = new MyTimer(1000, i);
                t.start();
                t.addEventListener(TimerEvent.TIMER, te);
        }       
 
        private function te(e :TimerEvent):void{
                trace(e.target.id);
        }


iNils 08.07.2009 14:20

Третий вариант вполне ничего или напишите класс TimerID унаследованный от Timer, и опишите в нем это свойство.

dimarik 08.07.2009 14:26

А зачем Вам вообще этот i? Сделате класс контейнера в котором композицией пропишите таймер. Диспатчите TimerEvent от имени контейнера. Подпишите контроллер на этот эвент. Делов-то!

wvxvw 08.07.2009 14:28

Если вы добавили таймер в массив, то у него уже есть индекс - его положение в массиве. Но лучше для таких целей использовать Dictionary, т.как в массив один и тот же таймер можно добавить много раз, а в Dictionary - только 1. Не вижу большого смысла в создании дополнительных классов только ради одного свойства. Кроме того, я бы не стал создавать много таймеров - а один, и подисывался / отписывался от него, когда нужно.

vvvvvvf 08.07.2009 14:59

Меня вообще не устраивает тот факт, что я должен ради этого создавать отдельный класс который будет расширяться от Timer, то есть (MyTimer extends Timer), можете дать пример где не надо создавать отдельный класс, а прямо в текущем коде (Код #3) можно расширить экземпляр экземпляр myTimer[i] и добавить в него свойство id?

Добавлено через 1 минуту
Цитата:

Сообщение от iNils (Сообщение 833932)
Третий вариант вполне ничего.

Можете дать какой нибудь пример как можно правильно реализовать задуманный третий вариант?

wvxvw 08.07.2009 15:03

>> а прямо в текущем коде (Код #3) можно расширить экземпляр экземпляр myTimer[i] и добавить в него свойство id?

Дык, говорю же, не нужно ничего расширять - вам нужен индекс из массива -
Код AS3:

var array:Array = [timer1, timer2];
trace(array.indexOf(timer1));

но лучше Dictionary
Код AS3:

var d:Dictionary = new Dictionary();
d[timer1] = 1;
d[timer2] = 2;
trace(d[timer1]);


iNils 08.07.2009 15:06

Класс Timer не динамический, поэтому "расширять" экземпляры нельзя. Вообще "расширять экземпляры" и "не устраивает тот факт.." это с ног на головы, должно быть как раз наоборот.

dimarik 08.07.2009 15:08

Цитата:

Сообщение от vvvvvvf (Сообщение 833948)
можете дать пример где не надо создавать отдельный класс, а прямо в текущем коде расширить экземпляр экземпляр myTimer[i]

Это были люди большого богатства. Но они хотели странного. (с) АБС

vvvvvvf 08.07.2009 15:11

Жизненных ситуаций очень много и я все же хотел был знать как расширять текущий экземпляр не создавая новый класс.

Например в таком коде:
Код AS3:

package {
        import flash.display.*;
        import flash.events.*;
        import flash.utils.*;
 
        public class myClass extends Sprite {
                private var myTimer:Timer;
 
                public function myClass():void {
                        var i:Number = 0;
                        myTimer = new Timer(1000);
                        // каким-то чудесным способом мы
                        // тут добовляем экземпляру
                        // новое свойство id
                        myTimer.id;
                        // а тут уже присваиваем этому
                        // свойству само значения переменной i
                        myTimer.id = i;
                        myTimer.start();
                        myTimer.addEventListener(TimerEvent.TIMER, doTime);
                }
                public function doTime(e:TimerEvent):void {
                        // а в самой функции обработчеке мы уже
                        // достаем это свойство id и
                        // присваиваем его к переменной i
                        var i:Number = e.currentTarget.id;
                        trace('i:'+i);
                }
        }
}


вот еще раз повторю вопрос:
Как в текущей ситуации экземпляру myTimer присвоить новое свойство id не создавая отдельный класс?

iNils 08.07.2009 15:13

А я еще раз повторю
Цитата:

Класс Timer не динамический, поэтому "расширять" экземпляры нельзя.

vvvvvvf 08.07.2009 15:19

Цитата:

Сообщение от iNils (Сообщение 833962)
А я еще раз повторю: Класс Timer не динамический, поэтому "расширять" экземпляры нельзя.

Хорошо тут понятно, тогда исходя из кода в 10 посте как можно обратиться к переменной i не создавая новый класс?

iNils 08.07.2009 15:28

wvxvw идею кинул с Dictionary

vvvvvvf 08.07.2009 15:38

Цитата:

Сообщение от iNils (Сообщение 833966)
wvxvw идею кинул с Dictionary

Нее я говорю вот про такой код.
Как не создавая новых классов и не объявляя i в самом классе на подобие (private var i:Number), переменная i заданна строго в конструкторе, как обратиться к ней в функции обработчике?

Код AS3:

package {
        import flash.display.*;
        import flash.events.*;
        import flash.utils.*;
 
        public class myClass extends Sprite {
                private var myTimer:Timer;
 
                public function myClass():void {
                        var i:Number = 0;
                        myTimer = new Timer(1000);
                        myTimer.start();
                        myTimer.addEventListener(TimerEvent.TIMER, doTime);
                }
                public function doTime(e:TimerEvent):void {
                        // Как тут получить i?
                }
        }
}


etc 08.07.2009 15:40

Никак.

vvvvvvf 08.07.2009 15:49

Цитата:

Сообщение от __etc (Сообщение 833971)
Никак.

Ну наконец-то хоть один честный ответ без размазывания соплей...

iNils 08.07.2009 15:58

Цитата:

Сообщение от vvvvvvf (Сообщение 833973)
Ну наконец-то хоть один честный ответ без размазывания соплей...

Первое предупреждение.

wvxvw 08.07.2009 16:04

Цитата:

Сообщение от vvvvvvf (Сообщение 833969)
Нее я говорю вот про такой код.
Как не создавая новых классов и не объявляя i в самом классе на подобие (private var i:Number), переменная i заданна строго в конструкторе, как обратиться к ней в функции обработчике?

Код AS3:

package {
        import flash.display.*;
        import flash.events.*;
        import flash.utils.*;
 
        public class myClass extends Sprite {
                private var myTimer:Timer;
 
                public function myClass():void {
                        var i:Number = 0;
                        myTimer = new Timer(1000);
                        myTimer.start();
                        myTimer.addEventListener(TimerEvent.TIMER, doTime);
                }
                public function doTime(e:TimerEvent):void {
                        // Как тут получить i?
                }
        }
}


переменная i умрет как только выполнится конструктор - поэтому получить ее неоткуда... вообще не понятно, что вы хотели в этом коде сделать :/

Smrad 08.07.2009 18:32

Это называется замыканием
http://ru.wikipedia.org/wiki/%D0%97%...D%D0%B8%D0%B5)
Но as3 не умеет замыкать функции.

dimarik 08.07.2009 18:51

Цитата:

Сообщение от Smrad (Сообщение 834026)
Это называется замыканием. Но as3 не умеет замыкать функции.

Судя по коду JavaScript из того примера, as3 прекрасно умеет замыкать функции =)

Код AS3:

function createCounter() {
  var numberOfCalls = 0;
  return function() {
      return ++numberOfCalls;
  }
}
var fn = createCounter();
trace(fn()); //1
trace(fn()); //2
trace(fn()); //3


Smrad 08.07.2009 21:34

Цитата:

Сообщение от dimarik (Сообщение 834034)
Судя по коду JavaScript из того примера, as3 прекрасно умеет замыкать функции =)

Код AS3:

function createCounter() {
  var numberOfCalls = 0;
  return function() {
      return ++numberOfCalls;
  }
}
var fn = createCounter();
trace(fn()); //1
trace(fn()); //2
trace(fn()); //3


Ну, всё-таки, это не совсем то, чего хотелось бы.

wvxvw 08.07.2009 21:45

Это один в один пример из википедии - а чего вам хотелось бы? :)
кроме того, в АС так лучше не делать.

Smrad 09.07.2009 10:48

Цитата:

Сообщение от wvxvw (Сообщение 834091)
Это один в один пример из википедии - а чего вам хотелось бы? :)
кроме того, в АС так лучше не делать.

Ну, хотелось бы замыкать на локальный контекст, т.е. чтобы для стека замыкания создавалась копия стека контекста, грубо говоря, чтобы работал сабж.
А почему в АС так не нужно делать, где я упускаю?

iNils 09.07.2009 11:39

Цитата:

А почему в АС так не нужно делать, где я упускаю?
Был у вас Запорожец (AS1), на котором вы за картошкой ездили. Теперь у вас Mercedes S600 (AS3), а вы на нем тоже в поле за картошкой поедете?

Smrad 09.07.2009 12:22

Цитата:

Сообщение от iNils (Сообщение 834190)
Был у вас Запорожец (AS1), на котором вы за картошкой ездили. Теперь у вас Mercedes S600 (AS3), а вы на нем тоже в поле за картошкой поедете?

Я AS1/AS2 в глаза не видел, поэтому не уверен, что правильно понял мысль. Чем лямбда мешает AS3? Само-собой я не говорю о подписке на лямбду,

BlooDHounD 09.07.2009 12:51

http://www.flasher.ru/forum/showpost...77&postcount=7
http://www.flasher.ru/forum/showpost...4&postcount=19

Smrad 09.07.2009 13:14

Цитата:

Сообщение от BlooDHounD (Сообщение 834217)

Всё ясно, не кто не против лямбды, просто она криво реализована в as3.

BlooDHounD 09.07.2009 15:45

Smrad, просто она не нужна в АС3.

DeliMIter 09.07.2009 15:57

Цитата:

Сообщение от BlooDHounD (Сообщение 834257)
Smrad, просто она не нужна в АС3.

Последнее слово лишнее.

Smrad 09.07.2009 18:08

Цитата:

Сообщение от DeliMIter (Сообщение 834265)
Последнее слово лишнее.

Ага, а особенно бесполезна в функциональных языках ;).

Добавлено через 6 минут
Цитата:

Сообщение от BlooDHounD (Сообщение 834257)
Smrad, просто она не нужна в АС3.

Зачем добавлять в язык ненужные возможности?

DeliMIter 09.07.2009 18:24

Цитата:

Сообщение от Smrad (Сообщение 834309)
Зачем добавлять в язык ненужные возможности?

Предположу, что для поддержания ECMA-стандарта, на котором основан AS3.

Smrad 09.07.2009 19:05

Цитата:

Сообщение от DeliMIter (Сообщение 834315)
Предположу, что для поддержания ECMA-стандарта, на котором основан AS3.

Надо полагать, что в ECMA анонимные функции попали по ошибке ;).

DeliMIter 09.07.2009 19:17

Есть конструктивное предложение не холиварить. Про "нужна или не нужна" я пошутил.

Есть вещи, которые можно сделать тем или иным способом, и некоторые из этих способов я не использую, потому что их логика, с моей точки зрения, отличается от логики остального языка. То вышеупомянутые анонимные функции, интервалы и таймауты, а в AS2 были ещё и микс-ины, бродкастер и доступ к как бы приватным свойствам через [].

Если разработчик понимает, что он делает, зачем, и как оно работает, это его личное дело (например, кажется, silin - большой любитель адских микс-инов в AS2), но вот давать такие примеры новичку, имхо, это бэд, очень бэд. Человек и так ещё не понимает, что такое область видимости, контекст, и т.д., а тут ему ещё и подсовывают нечто, требующее на два порядка более высокий уровень знаний.

MoHaX 09.07.2009 19:26

Сама задача весьма стрранно рещается.
зачем запускать 10 таймеров на 1 секунду.
достаточно запустить 1 таймер, и в его обработчике сделать цикл.

динамические классы, зло.

dimarik 09.07.2009 19:36

Цитата:

Сообщение от MoHaX (Сообщение 834336)
Сама задача весьма стрранно рещается.
зачем запускать 10 таймеров на 1 секунду.
достаточно запустить 1 таймер, и в его обработчике сделать цикл.

динамические классы, зло.

один таймер - много подписчиков. смысл тогда в диспетчере? зачем здесь циклы?

Smrad 09.07.2009 19:41

Цитата:

Сообщение от DeliMIter (Сообщение 834332)
Есть конструктивное предложение не холиварить. Про "нужна или не нужна" я пошутил.

Насчёт не холиварить я за. Просто не разобрал шутки и доколупался, т.к. сам большой любитель функциональщины.

dimarik 10.07.2009 02:34

Цитата:

Сообщение от BlooDHounD (Сообщение 834217)

Забавно, но при таком раскладе есть runtime error
Код AS3:

import flash.events.EventDispatcher;
function test():Function {
        return function(event:Event, whatever:Object):uint {
                trace(event, whatever);
                return 0;
        }
}
var dispatcher = new EventDispatcher();
dispatcher.addEventListener( 'test', test() );        // не всё окей
dispatcher.dispatchEvent( new Event( 'test' ) );


BlooDHounD 10.07.2009 02:53

dimarik, тем болие тупо.

dimarik 10.07.2009 03:02

Не ожидал, что в два часа ночи проснешься =)

По существу. Согласен с пунктом про сигнатуру анонимной функции. Она отсутствует на этапе компиляции для компилятора. А виртуальная машина ведет себя на анонимных функциях довольно странно. Поясню. В примере Блуда анонимная функа не принимала ни одного аргумента, добавив в неё два или более аргументов, получаем runtime error "Invalid arguments count"

MoHaX 10.07.2009 15:18

Код AS3:

package {
        import flash.events.TimerEvent;
        import flash.utils.Timer;               
 
        public class Test {
                private var timer : Timer;
                private var array : Array;
 
                public function Test() {
 
                        initArray();
 
                        timer = new Timer(1000);
                        timer.addEventListener(TimerEvent.TIMER, onTick);
                }
 
                private function initArray() : void {
                        array = new Array();
                        for (var i : uint = 0; i < 5; i++) {
                                var obj : Object = new Object();
                                obj["id"] = i;
                                array.push(obj);
                        }
                }
 
                private function onTick(event : TimerEvent) : void {
                        for (var i : uint = 0; i < array.length; i++) {
                                trace(array[i].id);
                        }
                }
        }
}



Часовой пояс GMT +4, время: 19:15.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.