Как мне структурировать несколько проектов Cairngorm MVC, которые имеют несколько компонентов?
Я недавно завершил проект для пользовательского интерфейса отчетов во Flex. Теперь мне поручено создать новое приложение, которое по сути является "облегченной" версией оригинального интерфейса. Он будет включать в себя только некоторые из опций, которые есть в исходном приложении. Также это должно быть отдельное приложение.
Я не хочу дублировать мой код, поэтому я планирую переместить несколько классов из исходного приложения в новую библиотеку, которая может использоваться обоими приложениями. Тем не менее, я пытаюсь выяснить, как заставить это работать в моей среде MVC.
Например, у меня есть компонент Accordion, который позволяет пользователям фильтровать несколько элементов. Каждый дочерний элемент Accordion является экземпляром пользовательского компонента с двумя списками (один для объектов, доступных для выбора, другой для объектов, выбранных пользователем). Каждый дочерний компонент имеет свойства, связанные с моделью, и функции, которые вызывают события Cairngorm.
Вот упрощенный пример:
FiltersAccordion.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:Accordion xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:local="*">
<mx:Script>
<![CDATA[
import model.ModelLocator;
[Bindable]
private var __model:ModelLocator = ModelLocator.getInstance();
]]>
</mx:Script>
<local:GenreFilter availableGenres="{__model.availableGenres}"
selectedGenres="{__model.selectedGenres}" />
<local:ArtistFilter availableArtists="{__model.availableArtists}"
selectedArtists="{__model.selectedArtists}" />
<local:LabelFilter availableLabels="{__model.availableLabels}"
selectedLabels="{__model.selectedLabels}" />
</mx:Accordion>
GenreFilter.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import control.events.AddGenresEvent;
import control.events.RemoveGenresEvent;
import model.ModelLocator;
[Bindable]
private var __model:ModelLocator = ModelLocator.getInstance();
[Bindable]
public var availableGenres:ArrayCollection;
[Bindable]
public var selectedGenres:ArrayCollection;
private function addGenresButton_clickHandler():void
{
var event:AddGenresEvent = new AddGenresEvent();
event.availableGenres = availableGenres;
event.selectedGenres = selectedGenres;
event.itemsToAdd = availableGenresList.selectedItems;
event.dispatch();
}
protected function removeGenresButton_clickHandler():void
{
var event:RemoveGenresEvent = new RemoveGenresEvent();
event.availableGenres = availableGenres;
event.selectedGenres = selectedGenres;
event.itemsToRemove = selectedGenresList.selectedItems;
event.dispatch();
}
]]>
</mx:Script>
<mx:List id="availableGenresList" dataProvider="{availableGenres}" />
<mx:VBox>
<mx:Button id="addButton" icon="{rightArrowIcon}" width="22"
height="22" click="addGenresButton_clickHandler();" />
<mx:Button id="removeButton" icon="{leftArrowIcon}" width="22"
height="22" click="removeGenresButton_clickHandler();" />
</mx:VBox>
<mx:List id="selectedGenresList" dataProvider="{selectedGenres}"
width="100%" height="100%" allowMultipleSelection="true" />
</mx:HBox>
ArtistFilter.mxml и LabelFilter.mxml имеют почти такой же дизайн, что и GenreFilter.mxml, но используются для их конкретных событий.
Так как мне это сделать? Нет смысла переносить мою модель в общую библиотеку. Я в основном хочу просто создать компоненты View в библиотеке. Я полностью сбился с толку, или как?
1 ответ
Это один из больших недостатков Cairngorm - ваши взгляды связаны с вашей моделью. Тем не менее, вы можете уменьшить большую часть боли, сделав нужные компоненты более универсальными и инкапсулированными. Затем расширьте их, чтобы связать их с остальной частью приложения.
Итак, ваш первый компонент становится:
<?xml version="1.0" encoding="utf-8"?>
<mx:Accordion xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:local="*">
<mx:Script>
<![CDATA[
[Bindable]
public var availableGenres:ArrayCollection;
[Bindable]
public var availableArtists:ArrayCollection;
[Bindable]
public var availableLabels:ArrayCollection;
[Bindable]
public var selectedGenres:ArrayCollection;
[Bindable]
public var selectedArtists:ArrayCollection;
[Bindable]
public var selectedLabels:ArrayCollection;
]]>
</mx:Script>
<local:GenreFilter availableGenres="{availableGenres}"
selectedGenres="{selectedGenres}" />
<local:ArtistFilter availableArtists="{availableArtists}"
selectedArtists="{selectedArtists}" />
<local:LabelFilter availableLabels="{availableLabels}"
selectedLabels="{selectedLabels}" />
</mx:Accordion>
Затем вы делаете это в каждом приложении (но с разными моделями / событиями).
<library:SpecialAccordion ...
availableGenres="{_model.availableGenres}"
availableArtists="{_model.availableArtists}"
... etc ...
>
<mx:Script>
<![CDATA[
import model.ModelLocator;
[Bindable]
private var __model:ModelLocator = ModelLocator.getInstance();
]]>
</mx:Script>
</library:SpecialAccordion>
Имеет ли это смысл? Это разница между "представлением" и "компонентом". Компоненты можно использовать повторно, а представления - нет. Компоненты инкапсулированы, представления зависят от приложения.