PDA

Просмотр полной версии : как повесить событие на не созданный объект


olejan1991
12.07.2012, 21:32
В представлении добавляются объекты с кнопками. как повесить на эти кнопки событие(нажатие мыши) из контроллера?

bav
12.07.2012, 22:54
Также как и всегда:
btn.addEventListener(MouseEvent.CLICK, clickHandler);

olejan1991
12.07.2012, 22:57
кнопка создается в классе View, а событие вешаю на него в классе Controller. Так вот если событие повесить в View, то все норм, но оно должно быть в Controller, а от туда оно не работает

Inet_PC
12.07.2012, 23:01
Может таки стоит кусочек кода привести?

olejan1991
12.07.2012, 23:06
да конечно
это класс Controller
package mvc {
import flash.display.MovieClip;
import flash.events.MouseEvent;

public class Controller {

private var _model:Model;

private var button:Type = new Type();

public function Controller()
{
trace(button);
}

public function get model():Model
{
return _model;

}

public function set model(m:Model):void
{
_model = m;
}

public function addNextButton():void
{
button.addEventListener(MouseEvent.CLICK, showNext);
}

private function showNext(e:MouseEvent):void{
trace("dd");
}




}

}


а это класс view, где создаются,собственно, кнопки,на которые хочу повесить событие
package mvc
{
import flash.text.TextField;
import flash.events.Event;
import flash.display.DisplayObject;//
import flash.display.Loader;
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.utils.Dictionary;


public class View
{
private var numbSquare:Number;

private var _model:Model;

private var square:Square;

private var container:Container;

private var btn:Type;

private var counter:Number = 0;

private var currentType:Array;

private var type:TextField;

private var squareWidth:Number;

private var squareHeight:Number;

private var dict:Dictionary = new Dictionary;

//private var arr:Array = new Array;

private var btns:Array = new Array;

public function View()
{
}

public function set model(m:Model):void
{
_model = m;
_model.addEventListener(Model.MODEL_CHANGED, update);
currentType = _model.currentType; ///////
}

private function update(e:Event):void
{
container = new Container();
container.y = 66;
DocumentClass.stage.addChild(container);
numbSquare = Number(_model.numbSquare);
squareWidth = Number(_model.width);
squareHeight = Number(_model.height);
outer:for (var i:int = 0; i < numbSquare; i++) // присваиваем циклу имя outer для возможности выхода из него
{
for (var j:int = 0; j < 6; j++)
{
if (counter == numbSquare)
{
break outer; //выход из цикла с именем outer
}
square = new Square();



type = new TextField();

btn = new Type();

type.x = 67; // расположение типа ячейки по оси х
type.text = String(currentType[counter]); // обращаемся к массиву с типами ячеек для вывода текущего типа текущей ячейки

square.width = squareWidth;// ширина ячеек
square.height = squareHeight;// высота ячеек
square.x = (squareWidth+5)*j;
square.y = (squareHeight+5)*i;

container.addChild(square);
square.addChild(type);
square.addChild(btn);
//btn.id = counter;
//btn.addEventListener(MouseEvent.CLICK, butId);
//btns.push(btn)
counter++;
}
}
setContainer(12); // 12 сделать динамическим
}

/*private function butId(e:MouseEvent):void{
var index:int = btns.indexOf(e.currentTarget);
trace(index);
}*/


private function setContainer(N:Number):void
{
container.ramka.width = (squareWidth+5) * N/2;//ширина контейнера сделать динамическое
container.ramka.height = (squareHeight+5) * N/6;

}

public function get model():Model
{
return _model;
}

}

}

olejan1991
12.07.2012, 23:33
Вот проект

strangedk
12.07.2012, 23:47
Может не стоит все таки так сильно рваться в MVC ?

Вы себе просто лишние проблемы создаете, разберитесь сначала как оно всё работает, сделайте приложение например просто с Singletone. А потом уже MVC.

Просто сейчас получается что вы пытаетесь прыгнуть выше головы, не зная одного уже хотите использовать другое.

olejan1991
13.07.2012, 00:01
Мне нужно именно МVC, поэтому и лезу в него

Добавлено через 1 минуту
Так что кто знает ответ на вопрос подскажите его мне пожалуйста

strangedk
13.07.2012, 00:08
кнопка создается в классе View, а событие вешаю на него в классе Controller. Так вот если событие повесить в View, то все норм, но оно должно быть в Controller, а от туда оно не работает

А кто вам сказал что события на кнопки должны быть в контроллере?
В вашем случае визуальный объект (главный View) должен отправлять события заинтересованным контроллерам или модели.

И кстати, а как так, что View у вас не наследник DisplayObject (Sprite, MovieClip) ?

bav
13.07.2012, 00:11
Функция addNextButton где-нибудь вызывается?

Wolsh
13.07.2012, 00:16
Контроллер не должен ничего знать о внутреннем устройстве Вью.
Во всей этой компании Вью — засланный казачок.
Что это значит на практике? Что Вью обязуется сообщать о действиях пользователя контроллеру.
Вью, а не его мелкие детальки. Контроллер общается с Вью, не с кнопками, которых может вообще не быть в конкретной реализации Вью.
То есть Вью разбирается с тем какую там кнопку нажали и сообщает контроллеру.
Сообщает не в стиле "нажали кнопку с id=9", а в стиле "юзер запросил операцию завершения игры".
Контроллер должен оперировать таким уровнем абстракции, который един для логики приложения.
Его не должны интересовать какие-то там кнопочки — а может это шорткаты? Или меню? Или диалоги?
Он занимается логикой. Интерфейсом занимается Вью.

olejan1991
13.07.2012, 00:22
Функция addNextButton где-нибудь вызывается?да, в document class

Добавлено через 14 минут
Изложу суть проблемы по порядку и как я вообще дошел до создания данной темы.
1.Есть объекты(квадраты(ячейки)) с кнопкой и текстовым полем. Все создается динамически.
2.Информация для текстового поля берется из массива, а туда она попадает из файла ХМЛ.
3.Мне необходимо при нажатии кнопки менять текстовое поле в ячейке, в которой была нажата кнопка.
4.Чтобы изменить информацию о текстовом поле в ячейке, в которой нажалась кнопка мне необходимо заменить в массиве свойство с id равным id ячейки в котором произошло нажатие.
А сама проблема в том, что я не могу понять каким образом мне присвоить ячейке id, в каком месте из компашки МVC это сделать, и как в итоге достучаться до того массива в моделе, который содержит информацию для текстовых полей и заменить свойство с нужным мне ключем для последующего его отображения.

Wolsh
13.07.2012, 02:35
1. Через контроллер (если нужен контроль): Нажали кнопку — Вью отсылает событие, например ViewEvent.CELL_CHANGED, содержащее данные: id ячейки.
Контроллер получает событие и отдает соответствующую команду Модели. Модель делает необходимые изменения и извещает об этом Вью. Вью обновляется.
Контроллер здесь "переводит" с языка Вью на язык Модели и решает, обрабатывать ли такой запрос вообще, или "не сезон".

2. Через Модель (если контроль не нужен): Вью сообщает Модели что надо изменить такое-то поле, Модель изменяется и сообщает Вью. Вью обновляется.
Здесь Модель должна обладать зачатками интеллекта и знать, что на что надо поменять, когда приходит такой запрос.

expl
13.07.2012, 12:59
В представлении добавляются объекты с кнопками. как повесить на эти кнопки событие(нажатие мыши) из контроллера?
Забудем на время слова "правильно" и "MVC" и подумаем что впринципе надо сделать
Участника у нас 3:
1. Кнопка
2. Главный контейнер (представление)
3. Контроллер
Условие: Кнопка появляется и исчезает неизвестно когда и по каким законам.

Вариант 1:
- тот, кто добавляет кнопку, подписывается на её клик и по клику диспетчит _кастомное_ событие THIS_CONCRETE_BUTTON_CLICK (диспетчить можно с контейнера, где лежит кнопка, или прямо с неё)
- событие должно быть со свойством bubbling = true
- событие всплывает до главного контейнера
- контроллер подписывается на THIS_CONCRETE_BUTTON_CLICK на главный контейнер (этот главный существует всегда и подписаться на него несложно)

Вариант 2:
- создаем класс ButtonWrapper extends Sprite, который при создании создаёт в себе кнопку и подписывается на событие CLICK и в ответ диспетчит с себя _кастомное_ событие THIS_CONCRETE_BUTTON_CLICK
- добавляем и удаляем везде не кнопку, а ButtonWrapper

Вариант 3:
- протягиваем тому, кто создаёт кнопку КОНТРОЛЛЕР
- тот кто создаёт кнопку, подписывается на CLICK, и по событию дёргает метод контроллера doSomethingOnThisConcreteButtonClick

Вариант 4:
- создаем класс ButtonWrapper, передаем ему в конструктор КОНТРОЛЛЕР,
- ButtonWrapper создаёт кнопку, подписывается на неё и вызвает метод doSomethingOnThisConcreteButtonClick
- везде тягаем ButtonWrapper вместо кнопки

Вариант 5.
?

olejan1991
13.07.2012, 19:53
Спасибо, буду пробовать.