Просмотр полной версии : вызов метода во всех экземплярах класса без использования цикла for
Добрый день, такой вопрос...
1. есть класс кнопки
2. на сцене лежит несколько экземпляров класса (меню)
3. В конструкторе класса подписываю кнопку на прослушивание пользовательского события(customEvent). Соответствующий обрабатывающий метод определен в классе кнопки.
При клике на кнопку (в методе обработки клика) пишу dispatchEvent(customEvent). Все хорошо, но мне нужно, чтобы реагировали все экземпляры класса, а в этом случае событие обрабатывается только кнопкой на которую я кликнул. Варианты с циклом for не рассматриваются.
Я делал это в AS2, но тут ничего не получается:)
вот:
package Classes{
import flash.events.Event;
public class ConstructorEvents extends Event
{
public static const BTN_STATUS:String = "btnStatus";
public function ConstructorEvents(type:String) {
super(type);
}
}
package Classes{
import flash.display.MovieClip;
import flash.events.Event;
import Classes.ConstructorEvents;
public class MenuButton extends MovieClip
{
public var event:ConstructorEvents = new ConstructorEvents(ConstructorEvents.BTN_STATUS);;
public function MenuButton()
{
addEventListener(ConstructorEvents.BTN_STATUS,onStatus);
addEventListener("click",onClick);
addEventListener("rollOver",onRollOver);
addEventListener("rollOut",onRollOut);
}
private function onClick(evt:Event):void
{
dispatchEvent(event);
}
private function onRollOver(evt:Event):void
{
}
private function onRollOut(evt:Event):void
{
}
public function onStatus(evt:Event):void
{
trace(evt.target.name);
}
}
}
Для начала экземпляр ивента надо создавать в самом методе.
И нужно сделать класс-контейнер, который будет принимать события от кнопок и оповещать остальные.
Для начала экземпляр ивента надо создавать в самом методе.
Делал и так тоже. Что это меняет? Или это есть просто правильный подход?
И нужно сделать класс-контейнер, который будет принимать события от кнопок и оповещать остальные.
Пробовал что-то подобное, но видимо что-то не так..ладно, буду пытаться еще
Делал и так тоже. Что это меняет? Или это есть просто правильный подход?
В целом это правильный подход.
И нужно сделать класс-контейнер, который будет принимать события от кнопок и оповещать остальные.
Сделал я это, но это не то, все равно при оповещении нужно перебрать все экземпляры кнопок, оповестить каждую индивидуально...
Зачем? Класс-контейнер является диспетчером.
а ты как хотел? можешь один раз в процессе сождания подписать все кнопки друг на друга... но помоемому будет просто полная лажа
можешь один раз в процессе сождания подписать все кнопки друг на друга... но помоемому будет просто полная лажа
согласен:)
Ну для начала, можно в классе контейнере подписаться на btnStatus у самого себя. При этом событие должно быть всплывающим.
__etc, ты имел ввиду что класс контейнер должен расширять EventDispatcher или я не понял..?
Да. Ну если у тебя кнопки лежат в спрайте, то он и так диспетчер.
кнопки лежат в MovieClip-e
рут расширяет спрайт, в нем контейнер - мувиклип, а кнопки в контейнере
Ну вот мувиклип и сделать классом-контейнером.
ну вот код класса контейнера ( я сделал его спрайтом все таки)
package Classes{
import flash.events.Event;
import Classes.ConstructorEvents;
import flash.display.Sprite;
public class ConstructorContainer extends Sprite
{
private var event:ConstructorEvents;
public function ConstructorContainer()
{
event = new ConstructorEvents(ConstructorEvents.BROADCAST_ALL);;
addEventListener(ConstructorEvents.BTN_STATUS, broadcastMess);
}
public function broadcastMess(evt:Event)
{
//обращаясь конкретно к экземплярам я могу передать событие, но нельзя ли передать всем сразу?
this.startAgain.dispatchEvent(event)
this.changeBasic.dispatchEvent(event)
}
}
}
}
что то не так, видимо, я чего то не догоняю...
package Classes{
import flash.events.Event;
import Classes.ConstructorEvents;
import flash.display.Sprite;
public class ConstructorContainer extends Sprite {
public function ConstructorContainer() {
addEventListener(ConstructorEvents.BTN_STATUS, broadcastMess);
for (var i:uint = 0;i < this.numChildren;i++) {
var child:MenuButton = this.getChildAt(i) as MenuButton;
if (child) {
child.addEventListener('broadcastAll', child.broadcastAllHandler);
}
}
}
public function broadcastMess(evt:Event)
{
dispatchEvent(new ConstructorEvent('broadcastAll'));
}
}
}
}
package Classes{
import flash.events.Event;
public class ConstructorEvent extends Event
{
public static const BTN_STATUS:String = "btnStatus";
public static const BROADCAST_ALL:String = 'broadcastAll';
public var menuButton:MenuButton;
public function ConstructorEvent (type:String, bubbles:Boolean = false) {
super(type, bubbles);
}
}
package Classes{
import flash.display.MovieClip;
import flash.events.Event;
import Classes.ConstructorEvents;
public class MenuButton extends MovieClip
{
public function MenuButton()
{
addEventListener(ConstructorEvents.BTN_STATUS,onStatus);
addEventListener("click",onClick);
addEventListener("rollOver",onRollOver);
addEventListener("rollOut",onRollOut);
}
private function onClick(evt:Event):void
{
var event:ConstructorEvent = new ConstructorEvent(ConstructorEvent.BTN_STATUS, true);
dispatchEvent(event);
}
private function onRollOver(evt:Event):void
{
}
private function onRollOut(evt:Event):void
{
}
public function onStatus(evt:Event):void
{
trace(evt.target.name);
}
public function broadcastAllHandler(event:ConstructorEvent):void {
if (event.menuButton != this) {
trace(this.name);
}
}
}
}
О, спасибо __etc! Щас буду смотреть.
и возврашаясь к циклу, цикл в данном случае будет быстрее чем диспач событий.
контейнер слушает кнопки, кнопки слушают контейнер - все оч просто
но цикл быстрее, готов поспорить на мороженое что быстрее :p
а там все равно без цикла не обходится)))
for (var i:uint = 0;i < this.numChildren;i++) {
var child:EditMenuButton = this.getChildAt(i) as EditMenuButton;
if (child) {
//trace(child)
child.addEventListener('broadcastAll', child.broadcastAllHandler);
}
}
__etc, извини канешно, а ты тестил свой код?))
Нет, не тестил. Я примерную схему описал.
__i, да быстрее цикл, быстрее. В силу создания очередной копии ивента и вообще его создания при каждой итерации. Но я не думаю, что это принципиально на паре десятков кнопок.
Со схемой я разобрался, спасибо.
я почему спросил..не работает код(
В классе ConstructorContainer не диспачится событие:
public function broadcastMess(evt:Event)
{
//вот тут глухо
dispatchEvent(new ConstructorEvent('broadcastAll'));
}
А сам обработчик broadcastMess работает?
Значит обработчик кнопок либо ничего не делает, либо не подписан на ивент.
возможно я не вполне проникся в чем тут трабл, тока я не вижу почему бы не заставить статический диспатчер вещать события на все экземпляры..
package {
import flash.display.MovieClip;
import flash.events.*;
public class MenuButton extends MovieClip{
static private var dispatcher:ButDispatcher=new ButDispatcher();
public function MenuButton(){
dispatcher.addEventListener(ButDispatcher.BTN_STATUS, onStatus);
addEventListener("click",onClick);
addEventListener("rollOver",onOver);
}
private function onClick(evt:Event):void{
dispatcher.broadcast("click");
}
private function onOver(evt:Event):void{
dispatcher.broadcast("over");
}
public function onStatus(evt:ButEvent):void{
trace(name+":"+evt.status);
}
}
}
package {
import flash.events.*;
class ButDispatcher extends EventDispatcher {
public static var BTN_STATUS:String = "btnStatus";
public function broadcast(status:String):void {
dispatchEvent(new ButEvent(ButDispatcher.BTN_STATUS,status));
}
}
}
package {
import flash.events.Event;
public class ButEvent extends Event{
public var status:String;
public function ButEvent(type:String,status:String=null){
super(type);
this.status=status;
}
}
}
насчет того что цикл быстрее, есть большие сомнения: нативные методы (а там тот же цикл) всегда быстрее скриптовых, во всяком случае AsBroadcaster в AS2 выигрывает у цикла в таких случая в разы, здесь не проверял..
Вооот!
silin, большое спасибо, это именно то!:drinks:
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.