Как структурировать несколько проектов Cairngorm MVC, которые имеют несколько компонентов? - PullRequest
0 голосов
/ 05 июня 2009

Я недавно завершил проект для пользовательского интерфейса отчета во 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 Ответ

2 голосов
/ 05 июня 2009

Это один из больших недостатков 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>

Это имеет смысл? Это разница между «представлением» и «компонентом». Компоненты можно использовать повторно, а представления - нет. Компоненты инкапсулированы, представления зависят от приложения.

...