![]() |
Как делать ветвление структуры в MVC?
Есть Document Class, в котором размещён код прелоадера. После загрузки создаётся класс Main, в конструкторе которого инициализируются модель, вью и контроллер. Контроллеру говорим грузить данные. Он говорит модели перейти в состояние "загрузка данных" и начинает грузить данные. Вью, получив от модели событие изменения состояния, показывает что грузятся данные.
Данные загрузились. Говорим модели перейти в основное состояние, она говорит об этом вью. А вот дальше... Сайт имеет несколько модулей: для показа текста, для показа фоток итд. Каждый модуль так же грузит данные для своих нужд. В общем появляется понятие модуля. Контроллер получает событие о переходе в основное состояние и в ответ на это говорит модели, какой модуль надо показывать. Модель в ответ на это посылает событие о том, что изменился активный модуль. Итак, ситуация: всё загрузилось, в контроллер пришло событие что нужно показывать такой-то модуль. Что делать дальше? Где должны располагаться модель, вью и контроллер модуля? Должны ли они быть обособлены, или каждая часть должна быть создана как дочерний объект глобальных M, V и С? Как передать им управление? Как организовать общение с главной связкой? |
Создавайте отдельные MVC-структуры друг в друге, в соответствии с моделью display object на экране.
|
etc, вот я и пытаюсь понять, как запихивать их друг в друга. Что внутри чего должно быть?
|
Модель в модели, вьювер во вьювере. Контроллерам же обычно достаточно управлять на уровне корневых элементов.
|
Спасибо, буду пробовать и спрашивать вопросы по мере возникновения.
|
__etc, а можно ли делать дочернее MVC полностью внутри вьювера?
Вот, например, у меня есть какой-нибудь хитрый контроллер-компонента, сделанный по принципу MVC, и я им хочу заменить стандартную кнопку. Он работает и без родительской модели автономно в принципе. Зачем его внутреннюю модель выносить наружу? |
s8000_1, я не понял вопроса. Ни того, ни другого. Модель во вьювере не хранится, это первое. Внутреннюю модель тоже никто никуда не выносит, более того, не мешают модели, контроллеры и представления в одну кучу.
|
__etc, разверну...
Есть визуальная AS3-компонента (типа DataGrid и т. п.) с понятным и логичным внешним интерфейсом. Но взаимодействие составных частей внутри компоненты устроено по принципу MVC: своя модель, свой внутренний контроллер и свое представление. Я хочу эту компоненту прилепить к большому приложению (его представлению). Получится, что MVC-компонента находится внутри представления другого MVC-большого приложения. Это разве не правильно? |
s8000_1, ваще, если быть честным с общественностью, то DataGrid это чистый вьювер. ведь данные вы ему отдельно кормите? конечно всё зависит от реализации, но по идеологии он должен быть вьювером.
|
BlooDHounD, так я как пример привел. Можно ведь соорудить гораздо более сложный компонент, для которого удобнее использовать внутри MVC (10 DataGrid'ов, 20 кнопочек и все это хитрым способом взаимодействует).
Поэтому я не совсем понимаю что значит "модель в модели". |
Модель в модели означает древовидную структуру данных, по аналогии со структурой вьюверов. Т. е., скажем, есть общая структура данных датагрида, внутри неё лежат структуры данных с информацией о каждом элементе датагрида.
Датагрид, получая ссылку на общую структуру (DataGridData), создает DataGridItem-ы у себя внутри и раздает им DataGridItemData, а те, в свою очередь, отображают данные из DataGridItemData. Если изменилось значение какого-либо поля в DataGridItemData, то на это среагирует конкретный вьювер, не DataGrid (которому в принципе положить на это изменение, если он сортировкой не занимается, конечно), а DataGridItem. Контроллер же управляет всем этим компонентом, в котором и DataGrid и кнопки, и прочие контролы. |
__etc, понятно
А если датагрид по нажатию какой-либо кнопки внутри себя сортирует данные, то как это организовать: он должен посылать контроллеру событие "сортировка", модель сортирует данные и обновляет датагрид? но ведь датагрид сам обновляется при сортировке данных =\ |
Нет, модель останется неизменной. А контроллер, если и принимает участие, только лишь в сохранении режима сортировки, а саму сортировку делает датагрид. Т. е. процесс сортировки за пределы датагрида не выходит, он всё делает сам, получает событие от своей же кнопки и т. д. При необходимости может выслать событие об изменении режима сортировки и всё.
|
__etc, Спасибо, теперь все намного яснее :)
у меня вопрос еще такой по MVC (не хочется плодить темы) Приложение создано для того, чтобы редактировать трансформации объекта на экране, менять их порядок и т. п. (графический редактор). Можно ли в модели хранить ссылки на конкретные объекты вместо массива матриц трансформаций? |
На объекты какого рода?
|
Ссылки на текстовые поля, битмапы.
Вместо того, чтобы хранить данные об объектах (координаты, матрицы трансформации, урлы картинок, текст текстового поля и др.) отдельно. Или это уже кривой подход? |
Модель должна хранить данные об объектах, а не ссылки на эти объекты.
|
У меня получилась вот такая вот модель, пока всем нуждам вполне удовлетворяет.
Код AS3:
|
GAIKER, это плохая реализация. Это просто по факту неуправляемый объект с неизвестным количеством свойств.
|
etc, что подразумевается под неуправляемым?
Насчёт свойств - почему такой подход хуже, чем загромождать модель объявлением каждого свойства плюс геттера и сеттера для него? |
Неуправляемый потому что туда может положить какие-угодно значения кто угодно.
А отсутствие геттеров и сеттеров — равносильно отсутствию типизации в коде. |
Думаю, было бы здорово открыть новый раздел, посвященный MVC. Обучение, примеры кода и т.д. Я несколько раз пытался въехать в этот фрэимворк, но пока выходит только чисто на интуитивном уровне.
|
MVC — это не фреймворк.
|
Извиняюсь, а что же это тогда? Архитектура ПО, шаблон?
|
Шаблон.
Не путайте с фреймворком PureMVC. |
Именно с Pure и попутал. Надо будет произвести себе ликбез по этим делам.
А вы пользуетесь шаблонами или фрэимфорками (если честно пока не особо понимаю разницу)? |
__etc, даже не шаблон. скорее идеология.
|
Лично я пользуюсь головой. :)
Для меня шаблоны (не только mvc, а всем пакетом) - концепция, не во всем отвечающая реальному миру, но полезная "для общего развития". Как законы Мерфи. ;) Как семиуровневая модель osi, не реализованная в каноническом виде никем, т.к. с практической точки зрения она не оптимальна. |
У меня назрел вопрос :rolleyes:
Допустим есть 2 элемента на экране: спрайт, который можно мышкой перетаскивать по экрану и текстовое инпут-поле, в которое можно забивать координаты этого спрайта. В модели должны храниться только координаты этого спрайта, как я понимаю. Вопрос касается событий. Как только мышкой передвигается спрайт на экране, то контроллер в модель пишет новые координаты, модель испускает событие CHANGE, которое слушает текстовое поле и соответственно в нем отображается координата модели. Однако же текстовое поле тоже может менять эту координату => CHANGE должен слушать и сам спрайт, изменяя соответственно свои координаты. Получается, что когда я мышкой двигаю спрайт, то модель испустит событие CHANGE, на которое подписан сам спрайт. Т. к. его координаты уже изменены, то естественно ничего не произойдет, однако лишняя функция вызовется. Как этого можно избежать? |
Спрайт сам себя переносить не должен, его перемещение контролирует контроллер, изменяя значения координат в модели. Спрайт, получая события от модели, ставится в нужное место на экране. Т. е. спрайт является прямым отображением состояния модели.
|
__etc, со спрайтом понятно.
А как быть с каким-нибудь List? Там selectedItem изменяется не извне контроллером, а изнутри все прописано. |
Ну и что, что не изменяется? Тот же selectedIndex можно задать контроллером, в чём проблема? Значение индекса выбранного элемента можно хранить в модели, если это требуется сохранить. В противном случае индекс живет, пока живет контроллер.
|
__etc, это понятно. Но я имею в виду примерно следующее:
Код AS3:
|
Для листа dataProvider-ом должна быть model. Это первое.
Второе: у контроллера не должно быть никаких публичных методов вообще, он должен сам создать лист (если требуется), отдать ему модель, сам подписаться на его события и менять модель. |
Это значит, что в программе взаимодействия листа и его внешнего управляющего элемента selectedItem вообще не должно находиться в модели. Взаимодействие элементов происходит только на уровне контроллера.
Пример - взаимодействие двух листов: выбираешь во втором => должно выбираться в первом и наоборот. модель: Код AS3:
Код AS3:
Правильно я понимаю? |
Нет, неправильно. Хотя бы потому что у разных моделей ни один узел в одном XML не равен другому узлу из другого XML. Соответственно хендлеры работать не будут. Необходимо использовать либо selectedIndex (что обычно проще), либо находить по какому-то критерию от узла одного XML другой узел другого XML и ставить его в качестве selectedItem у второго листа. Безусловно, этим занимается контроллер.
|
Все ясно, спасибо!
|
__etc, очень извиняюсь но у меня опять назрел вопрос из той же серии. Все никак не могу понять...
1) А как быть с текстовыми полями? Например, контроллер - текстовое инпут-поле, рядом с ним кнопка. По нажатию на кнопку в модели апдейтится поле text, туда посылается переменная text из текстового поля. Но это же поле модели может изменить кто-либо другой => контроллер слушает события модели на предмет апдейта этого поля text. По нажатию на кнопку я делаю апдейт модели. Модель испускает событие об изменении поля text внутри себя. Из-за этого события вызывается функция контроллера, которая апдейтит текстовое поле. Но оно уже изменилось до этого средствами флэша => эта функция вызвалась вхолостую. 2) А может ли контроллер быть наследником визуального класса, например Sprite? Ведь чтобы расположить вьюверы на экране, нужны какие-то данные (хотя бы stage). Или width, height для того, чтобы расположить вьюверы каким-то определенным образом. |
1) Это каким образом изменение модели прошло в обход контроллера? Контроллер, если и слушает изменение модели, то только лишь те изменения, которые требуют добавления/удаления вьюверов. В противном случае, изменения отслеживаются исключительно вьюверами. Ну а если подходить к возможным замкнутым рекурсиям, то в любом случае (в любом, это важно), в сеттере должна стоять проверка на текущее значение, типа if (this._somevalue === value) return;.
2) Он может иметь ссылку на контейнер-вьювер, но сам по себе визуальным объектом не может быть ни при каких обстоятельствах. |
__etc, ну зачем категорично? это комбо-система ... пример: любой уиконтрол :)
|
| Часовой пояс GMT +4, время: 12:31. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.