我正在尝试显示一小组分层数据,并且发现AdvancedDataGrid处理布局的方式非常糟糕我将尝试使用Spark列表以另一种方式处理它。
我从MySQL数据库获取LessCons的ArrayCollection。每个课程都有一个父主题(为了方便,我在每个课程中都包含了一个TopicName字段),我希望在按各自的主题对它们进行分组后显示课程。
我可以创建一个分层数据结构,可能是通过使用GroupingCollection2,并想知道我是否可以显示主题的Spark列表,并且在topicItemRenderer中我创建了一个给定主题的Spark课程列表?
任何想法都非常受欢迎。
克里斯
答案 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的文本属性。
最终名单
列表如下:
我花了很多天试图强迫AdvancedDataGrid来调整自己的大小并正确布局内容,这太可怕了。昨天我决定重新开始,这样做的效果会好得多。对于一个简单的分组列表,我建议采用类似的方法。
此致
克里斯
答案 1 :(得分:0)
你可以这样做,它会工作,但如果你有很多数据,这不是一个好主意。您将不得不担心项目渲染器。如果需要,我可能会使用树并创建自定义项呈示器。可能有些代码可能有所帮助。