如何构建共享多个组件的多个 Cairngorm MVC 项目?

发布于 2024-07-23 05:13:46 字数 3357 浏览 6 评论 0原文

我最近在 Flex 中完成了一个自定义报告 UI 项目。 现在,我的任务是创建一个新应用程序,该应用程序本质上是原始 UI 的“精简”版本。 它将仅包含原始应用程序中的一些选项。 此外,它需要是一个单独的应用程序。

我不想重复我的代码,因此我计划将一堆类从原始应用程序移动到可以由两个应用程序共享的新库。 但是,我正在尝试弄清楚如何在我的 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.mxmlLabelFilter.mxmlGenreFilter.mxml 的设计几乎相同,但用于其特定事件。

那么我应该怎么做呢? 将我的模型移至共享库是没有意义的。 我基本上想简单地在库中创建视图组件。 我是不是完全疯了,还是什么?

I recently completed a project for a custom report UI in Flex. Now, I've been tasked with creating a new application that is essentially a "lite" version of the original UI. It will include only a few of the options that are in the original application. Also, it needs to be a separate application.

I do not want to duplicate my code, so I am planning on moving a bunch of the classes from the original application to a new library that can be shared by both applications. However, I'm trying to figure out how to make this work in my MVC environment.

For example, I have an Accordion component that lets users filter several items. Each Accordion child is an instance of a custom component with two lists (one for entities available for selection, the other for the entities the user has selected). Each child component has properties bound to the Model and functions that call Cairngorm Events.

Here's an simplified example:

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 and LabelFilter.mxml are pretty much the same design as GenreFilter.mxml, but use to their specific Events.

So how should I do this? It doesn't make sense to move my Model into the shared library. I basically want to simply create View components in the library. Am I totally off my rocker here, or what?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

只怪假的太真实 2024-07-30 05:13:46

这是凯恩戈姆的一大缺陷——你的观点与你的模型息息相关。 也就是说,通过使想要重用的组件更加通用和封装,您可以减轻很多痛苦。 然后,扩展它们以将它们与应用程序的其余部分相关联。

因此,您的第一个组件变为:

<?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>

那有意义吗? 这是“视图”和“组件”之间的区别。 组件可以重用,而视图则不能。 组件是封装的,视图是特定于应用程序的。

That's one of the big flaws of Cairngorm - your views are tied to your model. That said, you can mitigate a lot of the pain by making the components you want reused more generic and encapsulated. Then, extend them to associate them with the rest of the app.

So, your first component becomes:

<?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>

Then, you do this in each application (but with different models / events).

<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>

Does that make sense? It's the difference between a "view" and a "component." Components can be reused, while views can't. Components are encapsulated, views are application-specific.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文