Flex List Within a List? -
i trying display small set of hierarchical data , have found advanceddatagrid terrible in how handles layout going try , approach way using spark lists.
i getting mysql database arraycollection of lessons. each lesson has parent topic (i have included topicname field within each lesson ease) , want display lessons after grouping them respective topics.
i create hierarchical data structure, possibly using groupingcollection2, , wondered if display spark list of topics , within topicitemrenderer create display spark list of lessons given topic?
any thoughts welcome.
chris
to create grouped list of data replaced advanceddatagrid spark list within spark list. has layout predictable , sizes properly. in case know have display approximately 20 items in grouped list don't have performance issues.
this how did it:
general - created new mxml component dedicated list of lessons. organise code following model, view, presenter pattern created lessonlist_view (mxml) , lessonlist_presenter (actionscript class). have model class (singleton) presenter classes instantiate put/get data. model raises events when properties change informing presenters, have eventlisteners, of change can update local properties of views bound. model calls php methods in amfphp service acquire data mysql database.
prepare data - have relational mysql database containing table of lessons , table of topics. each lesson has have 1 parent topic. topic have many lessons. using amfphp subset of lessons data. each lesson row database mapped flex class giving me arraycollection of typed value objects of type volesson. make life simpler included topicname field in volesson actionscript class, topicid available within mysql table, , included in select statement when getting data. sort data topic , lesson here ready next step.
next need create array collection containing arraycollections of lessons of same topic. way, figured, can have parent spark list displaying topics , within itemrenderer each topic list item can have list of lessons.
once lessonlist_presenter has got arraycollection of volessons iterate through it. new, temporary, arraycollection of lessons (_topiclessons) populated lessons until topicname changes whereupon add current _topiclessons arraycollection of volessons parent arraycollection (coursetopiclessons).
the function follows:
private function updatecoursetopiclessons():void { // reset coursetopiclessons. this.coursetopiclessons = new arraycollection(); // create variable hold last topicname. var _topicname:string = ""; // create arraycollection hold of lessons single topic. var _topiclessons:arraycollection = new arraycollection(); // iterate through courselessons. each(var _lesson:volesson in this.courselessons) { // check see if lesson has different topicname. if (_lesson.topicname != _topicname) { //trace("different topic: " + _lesson.topicname); // add previous _topiclessons coursetopiclessons arraycollection. if (_topiclessons.length > 0) { //trace("adding _topiclessons " + _topiclessons.length + " coursetopiclessons"); this.coursetopiclessons.additemat(_topiclessons, 0) } // new topic. reset _topiclessons. //trace("reset _topiclessons"); _topiclessons = new arraycollection(); // update _topicname. _topicname = _lesson.topicname; } // add lesson _topiclessons. //trace("add lesson: " + _lesson.lessontitle + " _topiclessons") _topiclessons.additemat(_lesson, 0); } // add previous _topiclessons coursetopiclessons arraycollection. if (_topiclessons.length > 0) { //trace("adding final _topiclessons " + _topiclessons.length + " coursetopiclessons") this.coursetopiclessons.additemat(_topiclessons, 0) } //trace(this.coursetopiclessons) }
i used .additemat() keep sort order correct.
views , itemrenderers - in lessonlist_view created list , set follows:
<!-- 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>
i used borders when checking see extents of lists.
my data provider arraycollection of arraycollections. want display list of topics , within each topic list item want display list of lessons. display topics know each arraycollection within parent arraycollection have @ least 1 volesson (i hope you're following this!). can display topicname value item. here code lesson list's 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 see if data property null. if (value== null) return; // if data property 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>
key thing remember itemrenderer passed data individual item in list, in case arraycollection of volesson objects. within element topicname first item in arraycollection of volessons passed in 'data' , set label's text property.
below topic label have list of lessons has same data provider, arraycollection of volesson objects same topic. itemrenderer list follows:
<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 see if data property null. if (value== null) return; // if data property 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>
remember 'data' object itemrenderer, , there 1 each item in list of lessons, single volesson object. in element lessontitle property volesson , set lessonlabel label's text property.
final list
the list appears follows:
i have spent many days trying coerce advanceddatagrid size , layout content properly, dreadful. yesterday decided start again , works better. simple grouped list recommend similar approach.
regards
chris
Comments
Post a Comment