I am using a nested repeater, where the dataProvider of the inner
repeater is an ArrayCollection of objects [buildings].  Each object
has an ArrayCollection of objects [people].  Think
Campus->Building->People scenario, where my outer repeater is looping
campuses and my
inner repeater is looping buildings and my inner repeater contains a
dataGrid of People.  My inner repeater also repeats a label component
that keeps count of the number of People in that Building by binding to
the length property on its People ArrayCollection.  This works
great, except the last Building in the last Campus does not update the
"People Count" when adding an item to its People ArrayCollection.

If that's confusing, please try the example code below.  In this example
case, if you click "Create Repeater Data" it  generates all the
campus/building/people just fine.  The "Employee Count" is updated
correctly.  However, if you click the "Add Employees" button it adds one
new employee to each building - this works totally fine, except for the
total count on employees on the last building.  The last building stays
at "Employee Count: 3", while the rest change to "Employee Count: 4".

I realize that I can call campus.buidingAC.refresh() (or
repeaterData.refresh()) and that will correct the problem, but in my
actual use-case this is too expensive.  I would be willing to add
building.employeeAC.refresh() after adding an employee, but I don't
believe it has any effect.

Is there some better way to do this?



<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml
<http://www.adobe.com/2006/mxml> " layout="vertical" >
  <mx:Script>
   <![CDATA[
    import mx.collections.ArrayCollection;

    [Bindable]
    private var repeaterData:ArrayCollection = null;

    private function createRepeaterData():void
    {
     var campusArr:Array = new Array();

     var i:uint = 0;
     var j:uint = 0;
     var k:uint = 0;
     var kLimit:uint = 0;

     for ( i=0; i<=3; i++ ) {
      var campus:Object = new Object();
      campus.label = "Campus " + i;

      var buildingArr:Array = new Array();
      for ( j=0; j<=4; j++ ) {
       var building:Object = new Object();
       building.label = campus.label + " Building " + j;

       var employeeArr:Array = new Array();

       for (kLimit = k+2; k<=kLimit; k++ ) {
        // make unique employees
        var employee:Object = new Object();
        employee.label = "Employee " + k;
        employeeArr.push(employee);
       }
       building.employeeAC = new ArrayCollection(employeeArr);
       buildingArr.push(building);
      }

      campus.buildingAC = new ArrayCollection(buildingArr);
      campusArr.push(campus);
     }

     repeaterData = new ArrayCollection(campusArr);
    }

    private function addEmployees():void
    {
     for each ( var campus:Object in repeaterData ) {
      for each ( var building:Object in campus.buildingAC ) {
       var employee:Object = new Object();
       employee.label = "New Employee (" + building.label + ")";
       building.employeeAC.addItem(employee);
      }
      // Note: employee count is updated correctly on the last building
when the following line is uncommented.
      //campus.buildingAC.refresh();
     }

    }

   ]]>
  </mx:Script>

  <mx:Button label="Create Repeater Data" click="createRepeaterData()" />
  <mx:Button label="Add Employees" click="addEmployees()" />

  <mx:Spacer height="20" />

  <mx:Repeater id="rp1" dataProvider="{repeaterData}">

   <mx:Label text="{rp1.currentItem.label}" fontWeight="bold" />

   <mx:Repeater id="rp2" dataProvider="{rp1.currentItem.buildingAC}" >
    <mx:Label text="{rp2.currentItem.label} - Employee Count:
{rp2.currentItem.employeeAC.length}" />

    <mx:Repeater id="rp3" dataProvider="{rp2.currentItem.employeeAC}" >
     <mx:Label text="{rp3.currentItem.label}" />
    </mx:Repeater>
    <mx:Spacer height="5" />

   </mx:Repeater>

   <mx:Spacer height="20" />
  </mx:Repeater>
</mx:Application>


Reply via email to