Чтобы создать сгруппированный список данных, я заменил свой AdvancedDataGrid на Spark List в Spark List. Теперь он имеет макет, который предсказуем и правилен. В моем случае я знаю, что мне нужно отображать примерно 20 элементов в моем сгруппированном списке, поэтому у меня нет проблем с производительностью.
Это, как я это сделал:
Общие - Я создал новый компонент MXML, посвященный списку уроков. Я организовываю свой код, следуя шаблону Model, View, Presenter, поэтому я создал LessonList_View (mxml) и LessonList_Presenter (класс ActionScript). У меня есть класс Model (Singleton), который классы-участники создают экземпляр для ввода/получения данных. Модель вызывает события, когда свойства изменяются, информируя докладчиков, у которых есть eventListeners, изменения, чтобы они могли обновлять свои локальные свойства, связанные с представлениями. Модель вызывает PHP-методы в службе Amfphp для получения данных из базы данных MySQL.
Подготовить данные - У меня есть реляционная база данных MySQL, содержащая таблицу уроков и таблицу тем. Каждый Урок должен иметь одну родительскую тему. Тема будет иметь много уроков. Я использую Amfphp для получения подмножества данных уроков. Каждая строка урока из базы данных отображается в класс Flex, предоставляя мне массив ArrayCollection строго типизированных объектов типа Type VoLesson. Чтобы упростить жизнь, я включил поле topicName в мой класс ActionScript ActionScript, только текстId доступен в таблице MySQL и включил это в мой оператор SELECT при получении данных. Я также сортирую данные по темам, а затем по Уроку здесь, чтобы он был готов к следующему шагу.
Далее Мне нужно создать массив массивов, содержащий ArrayCollections уроков одной и той же темы. Таким образом, я полагал, у меня может быть родительский список искр, отображающий темы и внутри ItemRenderer для каждого элемента списка тем, у меня может быть список уроков.
Как только мой LessonList_Presenter получил ArrayCollection of VoLessons, я перебираю его. Новый, временный, ArrayCollection of Lessons (_topicLessons) заполняется уроками до тех пор, пока не изменится имя темы, после чего я добавлю текущий _topicLessons ArrayCollection of VoLessons в родительский ArrayCollection (курсTopicLessons).
Функция выглядит следующим образом:
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 я создал этот список и установить его следующим образом:
<!-- 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>
я использовал границы, проверяя все, чтобы увидеть экстентов списков.
Мой поставщик данных - ArrayCollection of ArrayCollections. Я хочу отобразить Список тем и в каждом элементе списка тем. Я хочу отобразить Список уроков. Чтобы отобразить Темы, я знаю, что каждый 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 будет передаваться только данные для отдельного элемента в списке, в этом случае ArrayCollection объектов VoLesson. Внутри элемента я получаю topicName для первого элемента в ArrayCollection of VoLessons, переданного как «данные», и устанавливаю свойство текста Label.
Под меткой темы У меня есть список моих уроков, у которых есть тот же поставщик данных, массив ArrayCollection объектов VoLesson для той же темы. 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>
Помните, что объект «данных» для этого ItemRenderer, и там будет один для каждого элемента в списке уроков, будет единым объектом VoLesson. В элементе я получаю свойство lessonTitle из VoLesson и устанавливаю свойство text Label Label.
Окончательный список
Список выглядит следующим образом:
Я провел много дней, пытаясь принудить к AdvancedDataGrid к себе размер и расположение содержимого должным образом, это было ужасно. Вчера я решил начать снова, и это работает намного лучше. Для простого сгруппированного списка я бы рекомендовал аналогичный подход.
С уважением
Chris
вы можете сделать основной объект в списке и сбор в другом списке –
Идите вперед и попробовать его. Если это не сработает, у вас будет фураж для более детального вопроса :) – Brian