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>