列表中的Flex列表?

时间:2014-11-11 08:45:26

标签: list flex itemrenderer

我正在尝试显示一小组分层数据,并且发现AdvancedDataGrid处理布局的方式非常糟糕我将尝试使用Spark列表以另一种方式处理它。

我从MySQL数据库获取LessCons的ArrayCollection。每个课程都有一个父主题(为了方便,我在每个课程中都包含了一个TopicName字段),我希望在按各自的主题对它们进行分组后显示课程。

我可以创建一个分层数据结构,可能是通过使用GroupingCollection2,并想知道我是否可以显示主题的Spark列表,并且在topicItemRenderer中我创建了一个给定主题的Spark课程列表?

任何想法都非常受欢迎。

克里斯

2 个答案:

答案 0 :(得分:2)

要创建分组的数据列表,我将我的AdvancedDataGrid替换为Spark列表中的Spark列表。它现在具有可预测和适当大小的布局。在我的情况下,我知道我只需要在我的分组列表中显示大约20个项目,这样我就不会遇到任何性能问题。

我就这样做了:

一般 - 我创建了一个专门用于课程列表的新mxml组件。我按照Model,View,Presenter模式组织我的代码,因此我创建了LessonList_View(mxml)和LessonList_Presenter(ActionScript类)。我有一个Model类(Singleton),演示者类实例化它来放置/获取数据。当属性发生更改时,模型会引发事件,通知具有eventListeners的演示者,以便他们可以更新视图绑定的本地属性。 Model调用Amfphp服务中的PHP方法从MySQL数据库中获取数据。

准备数据 - 我有一个关系MySQL数据库,其中包含一个课程表和一个主题表。每个课程必须有一个父主题。主题将有很多课程。我正在使用Amfphp来获取Lessons数据的子集。数据库中的每个Lesson行都映射到Flex类,为我提供了类型为VoLesson的强类型值对象的ArrayCollection。为了简化生活,我在我的VoLesson ActionScript类中包含了topicName字段,只有topicId在MySQL表中可用,并在获取数据时包含在我的SELECT语句中。我还按主题排序数据,然后按课程排序,以便为下一步做好准备。

接下来,我需要创建一个包含相同主题的Lessons的ArrayCollections的Array Collection。这样,我想,我可以有一个父Spark列表显示主题,并在ItemRenderer中为每个主题列表项我可以有一个课程列表。

一旦我的LessonList_Presenter获得了VoLessons的ArrayCollection,我就会迭代它。使用Lessons填充一个新的临时ArrayCollection of Lessons(_topicLessons),直到topicName发生更改,然后将当前的_topicLessons的VoLessons ArrayCollection添加到父ArrayCollection(courseTopicLessons)中。

功能如下:

    private function updateCourseTopicLessons():void {

    // Reset courseTopicLessons.
    this.courseTopicLessons = new ArrayCollection();

    // Create a variable to hold the last topicName.
    var _topicName:String = "";

    // Create an ArrayCollection to hold all of the Lessons for a single Topic.
    var _topicLessons:ArrayCollection = new ArrayCollection();

    // Iterate through the courseLessons.
    for each(var _lesson:VoLesson in this.courseLessons)
    {
        // check to see if this lesson has a different topicName.
        if (_lesson.topicName != _topicName) {

            //trace("Different Topic: " + _lesson.topicName);

            // Add the previous _topicLessons into the courseTopicLessons ArrayCollection.
            if (_topicLessons.length > 0) {
                //trace("Adding _topicLessons " + _topicLessons.length + " to courseTopicLessons");
                this.courseTopicLessons.addItemAt(_topicLessons, 0)
            }

            // This is a new Topic. Reset _topicLessons.
            //trace("Reset _topicLessons");
            _topicLessons = new ArrayCollection();

            // Update _topicName.
            _topicName = _lesson.topicName;
        }

        // Add the Lesson to _topicLessons.
        //trace("Add Lesson: " + _lesson.lessonTitle + " to _topicLessons")
        _topicLessons.addItemAt(_lesson, 0);

    }

    // Add the previous _topicLessons into the courseTopicLessons ArrayCollection.
    if (_topicLessons.length > 0) {
        //trace("Adding final _topicLessons " + _topicLessons.length + " to courseTopicLessons")
        this.courseTopicLessons.addItemAt(_topicLessons, 0)
    }

    //trace(this.courseTopicLessons)

}

我使用.addItemAt()来保持排序顺序正确。

观看和ItemRenderers - 在我的LessonList_View中,我创建了List并将其设置如下:

<!-- Lessons List -->
    <s:List
            id="lessonList"
            dataProvider="{presenter.courseTopicLessons}"
            itemRenderer="views.LessonListTopicItemRenderer_View"
            borderVisible="false"
            borderColor="0xff69b4"
            preventSelection="true"
            contentBackgroundAlpha="0">

        <s:layout>
            <s:VerticalLayout
                    useVirtualLayout="false"
                    requestedMinRowCount="1"
                    gap="8"
                    paddingTop="8" paddingBottom="8"/>
        </s:layout>

    </s:List>

我在检查所有内容时使用了边框来查看列表的范围。

我的数据提供程序是ArrayCollections的ArrayCollection。我想显示主题列表,并在每个主题列表项目中我想显示课程列表。要显示主题,我知道父ArrayCollection中的每个ArrayCollection将至少有1个VoLesson(我希望你关注这个!)。我可以显示此项目的topicName值。这是我的课程列表的ItemRenderer的代码:

<s:ItemRenderer
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:presenters="presenters.*"
    width="100%" height="100%"
    autoDrawBackground="false">

<fx:Declarations>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
    <presenters:LessonListTopicItemRenderer_Presenter id="presenter"/>
</fx:Declarations>

<fx:Script>
<![CDATA[
    import models.Globals;
    import vo.VoLesson;

    override public function set data( value:Object ) : void {
        super.data = value;

        // Check to see if the data property is null.
        if (value== null)
            return;

        // If the data property is not null.
        var _lesson:VoLesson = VoLesson(value[0]);
        topicLabel.text = _lesson.topicName;

    }
    ]]>
</fx:Script>

<s:VGroup gap="8" width="100%">

    <!-- Divider line between Topics -->
    <s:Line id="topicDividerLine" width="100%">
        <s:stroke>
            <s:SolidColorStroke color="{presenter.selectedActivityColour_Mid}" weight="1" />
        </s:stroke>
    </s:Line>

    <!-- Topic Label -->
    <s:Label
            id="topicLabel"
            styleName="topicStyle"
            color="{presenter.selectedActivityColour}"
            maxWidth="{presenter.lessonsListTopicColumnWidth}" />

    <s:HGroup paddingLeft="{Globals.LESSONS_LIST_TOPIC_COLUMN_WIDTH}">
        <s:List
                id="lessonList"
                dataProvider="{data}"
                borderColor="0xadff2f"
                itemRenderer="views.LessonListLessonItemRenderer_View"
                borderVisible="false"
                preventSelection="true">

            <s:layout>
                <s:VerticalLayout
                        useVirtualLayout="false"
                        requestedMinRowCount="1"
                        gap="16"
                        paddingTop="8" paddingBottom="8"/>
            </s:layout>

        </s:List>
    </s:HGroup>

</s:VGroup>

要记住的关键是ItemRenderer将仅传递List中单个项的数据,在本例中是VoLesson对象的ArrayCollection。在元素中,我得到了传入VoLessons的ArrayCollection中第一个项目的topicName作为&#39;数据&#39;并设置我的Label的文本属性。

在主题标签下面,我有一个具有相同数据提供者的课程列表,一个同一主题的VoLesson对象的ArrayCollection。此列表的ItemRenderer如下:

<s:ItemRenderer
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:views="views.*"
    xmlns:presenters="presenters.*"
    height="100%"
    autoDrawBackground="false">

<fx:Declarations>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
    <presenters:LessonListLessonItemRenderer_Presenter id="presenter"/>
</fx:Declarations>

<fx:Script>
<![CDATA[
    import vo.VoLesson;

    override public function set data( value:Object ) : void {
        super.data = value;

        // Check to see if the data property is null.
        if (value== null)
            return;

        // If the data property is not null.
        var _lesson:VoLesson = VoLesson(value);
        lessonLabel.text = _lesson.lessonTitle;
    }
    ]]>
</fx:Script>

<s:HGroup gap="8" verticalAlign="middle">

    <views:IconLesson_View />

    <s:Label
            id="lessonLabel"
            styleName="lessonStyle"
            color="{presenter.textDarkGrey}"/>

</s:HGroup>

请记住,&#39;数据&#39;此ItemRenderer的对象,并且课程列表中的每个项目都有一个,将是一个VoLesson对象。在元素中,我从VoLesson获取lessonTitle属性并设置lessonLabel Label的文本属性。

最终名单

列表如下: enter image description here

我花了很多天试图强迫AdvancedDataGrid来调整自己的大小并正确布局内容,这太可怕了。昨天我决定重新开始,这样做的效果会好得多。对于一个简单的分组列表,我建议采用类似的方法。

此致

克里斯

答案 1 :(得分:0)

你可以这样做,它会工作,但如果你有很多数据,这不是一个好主意。您将不得不担心项目渲染器。如果需要,我可能会使用树并创建自定义项呈示器。可能有些代码可能有所帮助。