Архив

Powered by mod LCA

Разработка

Создание Flex-приложений c использованием Parsley. Часть 1, связывание

Когда мы начинаем писать приложение, на любой технологии, мы хотим написать "правильный" код, который позволял бы нам легко менять структуру приложения взаимосвязи между различными компонентами приложения. Хочется, чтобы одни модули/части проекта не зависели от других для дальнейшего использования.
Познакомившись с технологией Flex, которая мне понравилась, я в начале не придал внимания этому вопросу, и только после погружение в серьёзный проект я стал скучать по культовому в Java среде Spring. Начал смотреть на предмет аналогичных проектов для Flex приложений. Познакомившись с несколькими проектами я остановился на двух Spring Actionscript(в новом окне) и Parsley. Прочитав документацию, мне больше понравился второй вариант.
В этой статье и её приложении я опишу как я вижу возможность использования этой библиотеки для разработки приложения средней и высокой сложности.
Для примера я взял простой вариант с приложением "записная книжка", написанный как Air приложение, работающее с локальной БД SqlLight. Приступим.
Примечание: для этого примера я взял модифицированную таблицу с постраничной навигации вот из этого источника(в новом окне).
Parsley позволяет конфигурировать проект при помощи трёх вариантов MXML, AS и XML-вид. Все они решают одну и ту же задачу. Вопрос в том, что в одном случае удобно использовать один вариант в другом - другой В данном примере используются первые два варианта.. Для себя я определил сферы применения каждого следующим образом:
  • Общее конфигурирование проекта, связь между основными компонентами приложения, удобнее осуществлять в MXML-варианте
  • Организация связи (обмен сообщениями) между различными компонентами удобнее конфигурировать в AS-форме
  • Динамическая связь компонентов, в том числе и с учётом серверных ограничений (т.е. часть модулей приложения ограничена на стороне сервера) осуществляется в XML-виде.
Первая задача, которая встаёт перед нами - это написать все компоненты будущего проекта, сконфигурировать каждый из них и внедрить одни компоненты в другие.
Вот как выглядит файл объявления различных компонентов для нашего приложения
ContactbookConfig.mxml
<?xml version="1.0" ?>
<mx:Object xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:services="ru.gubber.sample.flex.controller.services.*"
xmlns:actions="ru.gubber.sample.flex.controller.actions.*"
xmlns:components="ru.gubber.sample.flex.view.component.*"
xmlns="http://www.spicefactory.org/parsley">
<services:LocalContactService id="service">
</services:LocalContactService>
<actions:ContactAction />
<components:MyButton />
<components:ContactPanel id="contactPanel"  width="100%" height="100%"/>
</mx:Object>
В данном примере у нас определено четыре компонента из различных уровней приложения. LocalContactService обеспечивает доступ к БД и обращение к физическим данным. ContactPanel - панель, которая отображает список контактов, а так же форму для добавления/редактирования контакта. Для использования данных компонентов мы должны сконфигурировать наше приложение, используя данный конфигурационный файл. Конфигурация, в моём случае происходит в основном классе Contactbook.mxml
<?xml version="1.0"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" 
 xmlns:views="ru.gubber.sample.flex.view.views.*"                        width="800" height="600" 
 preinitialize="FlexContextBuilder.build(ContactbookConfig)">
<mx:Script><![CDATA[
import org.spicefactory.parsley.flex.FlexContextBuilder;
]]></mx:Script>
<views:MainView width="100%" height="100%" />
</mx:WindowedApplication>
Конфигурирование приложения должно происходить как можно раньше, именно по этой причине создание контекста происходит по событию preinitialize. В данном случае во всё приложение у нас создаётся компонент MainView. Который и отвечает за отображение информации. Ниже приведено несколько фрагментов кода MainView, в которых происходит инициализация компонента и связывание его с компонентами в конфигурационном файле.
<?xml version="1.0" ?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%"
addedToStage="init(event)">
<mx:Script><![CDATA[

import flash.events.Event;

import ru.gubber.sample.flex.controller.massages.ContactMessage;
import ru.gubber.sample.flex.view.component.ContactPanel;
import ru.gubber.sample.flex.view.component.MyButton;
import ru.gubber.sample.flex.view.event.ApplicationEvent;

private var inited:Boolean = false;

[Inject]
public var aButton:MyButton;
[Inject]
public var panel:ContactPanel;

private function init(event:Event):void {
if (!inited) {
inited = true;
dispatchEvent(new Event('configureIOC', true))
}
}

]]></mx:Script>
<mx:VBox width="100%" id="vBox">
<mx:Button click="addingButton(event)" label="create DB" enabled="false" id="dbCreator"/>
</mx:VBox>
</mx:Canvas>
В данном примере кода происходит простое связывание компонентов, объявленных в данном класс и в файле конфигурации. При добавлении компонента в родительский объект генерируется событие dispatchEvent(new Event('configureIOC', true)), которое оповещает Parsley контекст, что данный компонент надо включить в обработку.
Примечание: переменная inited была введена для удаления избыточного добавления слушателей событий, пока мне не удалось разобраться в чём ошибка.
Теперь обратим своё внимание на 18 и 19 строчку. Как раз в этом месте и происходит прямое связывание переменной panel и компонента, который создаётся во время конфигурировании приложения. Т.к. у нас указана просто директива [Inject], то связывание происходит по классу объекта. Parsley ищет в конфигурации объект экземпляр данного класса, и связывает объект и переменную. Если же нам необходимо в конфигурации создать несколько объектов одного класса, и использовать их в различных местах, то для этого используется механизм выбора, когда в директиве указывается какой именно объект нам нужен. В случае с объектами для идентификации используется поле id, пример такого связывания можно увидеть в классе ContactAction.
package ru.gubber.sample.flex.controller.actions {
import ru.gubber.sample.flex.controller.services.IContactService;

public class ContactAction {

[Inject(id="service")]
public var service:IContactService;

...

}
}
На этом первую часть своего повествования я завершу. В следующей статье я опишу моменты связанные с обменом данными между различными компонентами приложения. В третьей части я опишу модель построения конкретного приложения с моим видением того как должно быть организовано правильное MVC приложение.

Добавить комментарий