Форум 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=139149)

nitsik 24.04.2010 15:27

Как передать параметр прослушивателю события?
 
Такая ситуация. Есть несколько MovieClip-ов, расположенных в массиве, например:
Код AS3:

Main.stairs[0] = new RightHeart;
Main.stairs[1] = new RightHeart;
Main.stairs[2] = new RightHeart;

Необходимо для каждого экземпляра мувика передать в функцию, которая реагирует на событие клика мышкой по мувику индекс мувика. Т. е. когда кликают по Main.stairs[0] в функции, реагирующие на возникновение события должна появляться переменная со значением 0; кликают по Main.stairs[1] - переменная со значением 1, по Main.stairs[2] - переменная со значением 2. Подскажите, как это можно сделать? Я так понял, что через какое-то свойство МувиКлипа? Код должен быть примерно таким (заранее неправильный):
Код AS3:

Main.stairs[key].addEventListener(MouseEvent.CLICK, function(e: Event) {
  var keyMovie = key;
});

Как сделать правильно? Заранее благодарен за ответы.

iflamberg 24.04.2010 15:38

много способов.
Самый элементарный - воспользоваться тем, что MovieClip - динамический класс
Код AS3:

for (var i:int=0; i<3; i++){
  var obj:RightHeart = new RightHeart ();
  obj.key = i; //у каждого объекта теперь свой key
  obj.addEventListener (MouseEvent.CLICK, clickHandler);
  Main.stairs.push(obj);
}
 
function clickHandler (e:Event):void {
  var obj:RightHeart = e.target as RightHeart;
  trace (obj.key); //какой key у объекта по которому кликнули?
}

Есть и другие пособы. Сделать свое собвстенное событие, или для не динамических классов применять почти такой же метод, что я привел, но данные хранить в Dictionary.

P.S. Не ленитесь ставить () после объявления экземпляра класса. Не создавайте функцию в addEventListener - они потом висят в памяти.

nitsik 24.04.2010 15:42

Спасибо за быстрый ответ и за замечания :-) Буду пробовать.

Wolsh 24.04.2010 17:39

Есть еще Array.indexOf()
)))
А правильнее по-моему просто завести в классе RightHeart свойство экземпляра key.

nitsik 24.04.2010 18:01

Цитата:

Сообщение от Wolsh (Сообщение 903140)
А правильнее по-моему просто завести в классе RightHeart свойство экземпляра key.

Т. е.:
Код AS3:

Main.stairs[key].key = key;

, правильно?

iflamberg 24.04.2010 18:07

не, это как раз мой способ, а он имеет ввиду создать класс

Код AS3:

package {
  public class RightHeart extends MovieClip {
    public var key:*;
  }
}

и связать его с мувиком. Так, как бы, правильнее, чтобы потом через много-много дней можно было вспомнить, какие свойства есть у объекта RightHeart, и откуда взялось key.

Wolsh 24.04.2010 18:11

Код AS3:

...
public class RightHeart extends MovieClip // или Sprite
{
    private var _key:uint;
    //....
    public function set key (value:uint):void { _key = value }
    public function get key ():uint { return _key }
}

Код AS3:

Main.stairs[i].key = i;

Т.е. то же, что предлагал iflamberg, только его вариант опирается на то, что МувиКлип - динамический класс. Т.е. со спрайтом например такой способ не пройдет. Да и просто грамотно - иметь фиксированные поля, а не создавать свойства "на лету" в рантайме. МувиКлип был оставлен динамическим не для такого использования, а по необходимости.

iflamberg 24.04.2010 18:15

А я такой *****кодер, такой *****кодер =) У меня даже есть
Код AS3:

package fbrg.utils {  public dynamic class DLoader extends Loader {}}

просто для того, чтобы в маленьких проектах не создавать новые классы расширяющие Loader для записи всего нескольких свойств.

BlooDHounD 24.04.2010 19:05

грамотнее, на самом деле, создавать хэши с "приватными" классами, в которых хранятся нужные вам значения.
Код AS3:

package {
 
        import flash.display.Sprite;
        import flash.events.MouseEvent;
        import flash.utils.Dictionary;
 
        /**
        * @author                        BlooDHounD
        * @playerversion        Flash 9
        * @langversion                3.0
        */

        public class test extends Sprite {
 
                public function test() {
                        super();
 
                        var mc:Sprite = new Sprite();
                        // создаём свойства не создавая наследников
                        this._hash[ mc ] = new MyProps();
                }
 
                private const _hash:Dictionary = new Dictionary();
 
                private function handler_click(event:MouseEvent):void {
                        var props:MyProps = this._hash[ event.target ];
                        // do something
                }
 
        }
 
}
 
internal final class MyProps {
 
        public function MyProps() {
                super();
        }
 
        public var var1:Number;
 
        public var var2:String;
 
}

если свойство всего одно, то можно вместо экземпляра класса записывать сразу значение.

iflamberg 24.04.2010 19:18

я класс Dictionary упоминал вторым постом =)

BlooDHounD 24.04.2010 19:37

iflamberg ну в коде Вы привели совсем другое. чего там дальше мимолётно упоминается я не обратил внимание =) да и думаю, что автору не очень было ясно как оно делается после вашего упоминания.

КорДум 26.04.2010 00:05

Извините, если здесь обсуждалось уже где-то, но вот по теме и, что самое главное, оно работает.
http://pavelk.ru/?p=235#respond

wvxvw 26.04.2010 00:21

Не делайте никогда, так как описано по ссылке. Это в первую очередь чревато засорением памяти, а во вторую просто не удобно.
Если вам не нравится то, что слушателя можно вызвать с всего одним параметром - напишите функцию, которая принимает больше параметров, и вызовите ее. Хотя ситуация, когда в одном параметре слушателя нельзя передать все, что вам нужно возникает крайне редко, мне даже тяжело представить ситуацию, когда она могла бы возникнуть...

BlooDHounD 26.04.2010 00:22

КорДум, никогда не делайте так как там написано.

Добавлено через 19 секунд
лол ) Олег опередил )

КорДум 26.04.2010 00:26

Хм, хорошо. Вот и ходи по блогам, собирай изобретенные велосипеды...

etc 26.04.2010 07:55

Цитата:

Сообщение от КорДум (Сообщение 903529)
Извините, если здесь обсуждалось уже где-то, но вот по теме и, что самое главное, оно работает.
http://pavelk.ru/?p=235#respond

Нет, я ещё понимаю, там, применять такое в JavaScript или AS1/AS2, где сплошняком проблемы с видимостью, но в AS3…

arkadattx 26.04.2010 11:51

Цитата:

Сообщение от КорДум (Сообщение 903529)
Извините, если здесь обсуждалось уже где-то, но вот по теме и, что самое главное, оно работает.
http://pavelk.ru/?p=235#respond

Цитата:

КорДум, никогда не делайте так как там написано.
Там же есть и другой варинат пользовательских событий: вот

Или тут не об этом?

mikhailk 26.04.2010 12:08

Имхо, если правильно перефразировать вопрос, то и проблема сама собой снимется.

Надо не искать способ передать параметр слушателю, а просто обеспечить ему необходимую информацию для дальнейших действий. Т.е., в идеале слушатель берет таргетный объект (уж его то он всегда знает) и получает информацию из его свойств/методов.

Соответственно, эту информацию мы должны заложить в объект в момент его порождения или как-то так, но до момента возникновения события. Что и было отражено в предлагаемых решениях.

BlooDHounD 26.04.2010 12:50

arkadattx, тот вариант не лучше =) человек не понимает вообще сути того что делает.
mikhailk, у-ук.

arkadattx 26.04.2010 12:54

BlooDHounD, а где можно почитать про более достойные способы?

ЗЫ. извиняюсь что не по теме.

Кстати по теме. Помню во время изучения ас2 очень понравилась фраза "субстрингом по неймам", т.е. почему нам не взять эту переменную из имени самого объекта? На сколько это будет верным решением? Мы при этом не создаем дополнительных переменных, не пишем (возможно) дополнительный класс, но при этом используем теже регэкспы.

BlooDHounD 26.04.2010 13:42

в этом топике можно прочитать.
из имени её брать не всегда получится. увы.

mikhailk 26.04.2010 14:00

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

но это неправильно
не надо так делать. :)


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

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