Просмотр полной версии : как повесить событие на не созданный объект
olejan1991
12.07.2012, 21:32
В представлении добавляются объекты с кнопками. как повесить на эти кнопки событие(нажатие мыши) из контроллера?
Также как и всегда:
btn.addEventListener(MouseEvent.CLICK, clickHandler);
olejan1991
12.07.2012, 22:57
кнопка создается в классе View, а событие вешаю на него в классе Controller. Так вот если событие повесить в View, то все норм, но оно должно быть в Controller, а от туда оно не работает
Может таки стоит кусочек кода привести?
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) ?
Функция addNextButton где-нибудь вызывается?
Контроллер не должен ничего знать о внутреннем устройстве Вью.
Во всей этой компании Вью — засланный казачок.
Что это значит на практике? Что Вью обязуется сообщать о действиях пользователя контроллеру.
Вью, а не его мелкие детальки. Контроллер общается с Вью, не с кнопками, которых может вообще не быть в конкретной реализации Вью.
То есть Вью разбирается с тем какую там кнопку нажали и сообщает контроллеру.
Сообщает не в стиле "нажали кнопку с id=9", а в стиле "юзер запросил операцию завершения игры".
Контроллер должен оперировать таким уровнем абстракции, который един для логики приложения.
Его не должны интересовать какие-то там кнопочки — а может это шорткаты? Или меню? Или диалоги?
Он занимается логикой. Интерфейсом занимается Вью.
olejan1991
13.07.2012, 00:22
Функция addNextButton где-нибудь вызывается?да, в document class
Добавлено через 14 минут
Изложу суть проблемы по порядку и как я вообще дошел до создания данной темы.
1.Есть объекты(квадраты(ячейки)) с кнопкой и текстовым полем. Все создается динамически.
2.Информация для текстового поля берется из массива, а туда она попадает из файла ХМЛ.
3.Мне необходимо при нажатии кнопки менять текстовое поле в ячейке, в которой была нажата кнопка.
4.Чтобы изменить информацию о текстовом поле в ячейке, в которой нажалась кнопка мне необходимо заменить в массиве свойство с id равным id ячейки в котором произошло нажатие.
А сама проблема в том, что я не могу понять каким образом мне присвоить ячейке id, в каком месте из компашки МVC это сделать, и как в итоге достучаться до того массива в моделе, который содержит информацию для текстовых полей и заменить свойство с нужным мне ключем для последующего его отображения.
1. Через контроллер (если нужен контроль): Нажали кнопку — Вью отсылает событие, например ViewEvent.CELL_CHANGED, содержащее данные: id ячейки.
Контроллер получает событие и отдает соответствующую команду Модели. Модель делает необходимые изменения и извещает об этом Вью. Вью обновляется.
Контроллер здесь "переводит" с языка Вью на язык Модели и решает, обрабатывать ли такой запрос вообще, или "не сезон".
2. Через Модель (если контроль не нужен): Вью сообщает Модели что надо изменить такое-то поле, Модель изменяется и сообщает Вью. Вью обновляется.
Здесь Модель должна обладать зачатками интеллекта и знать, что на что надо поменять, когда приходит такой запрос.
В представлении добавляются объекты с кнопками. как повесить на эти кнопки событие(нажатие мыши) из контроллера?
Забудем на время слова "правильно" и "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
Спасибо, буду пробовать.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.