Search code examples
apache-flexarraycollectiondataprovider

Flex 3: removing items from an array collection when the user clicks a button and reflecting that in a repeater


I have an arrayCollection with the following structure:

projectErrorsAC
    0
        project1number
        project2number
        position1number
        position2number
        project1name
        project2name
        student
    1
        ...

the AC is defined as follows:

[Bindable] private var projectErrorsAC:ArrayCollection = new ArrayCollection;

I'm using this AC in a repeater to display each error. After each error is shown, I've placed an "Accept" and "Deny" button. Once the user clicks either one of these buttons, I'd like to call a function that removes the particular error from the AC. Here's what I have so far:

Repeater:

<mx:Repeater id="projRP" width="100%" dataProvider="{projectErrorsAC}">
<mx:HBox>
    <mx:Text id="projmsg" text="{projRP.currentItem.student} is working on the following projects on the same day: {projRP.currentItem.proj1name} and {projRP.currentItem.proj2name}." />
    <mx:Text id="allow" text="Allow" color="#ff0000" selectable="false" 
        click="acceptProjConflict(projRP.currentItem);" 
        mouseOver="parentApplication.switchCursor(true);" 
        mouseOut="parentApplication.switchCursor(false);" />
    <mx:Text text=" |" />
    <mx:Text id="decline" text="Decline" color="#ff0000" selectable="false" click="declineProjConflict(projRP.currentItem);" mouseOver="parentApplication.switchCursor(true);" mouseOut="parentApplication.switchCursor(false);" />
</mx:HBox>
</mx:Repeater>

and here's the function I'm calling in the "click" part:

public function acceptProjConflict(conflict:Object):void
{
for (var i:int = 0; i < projectErrorsAC.length; i++)
{
    if (projectErrorsAC.getItemAt(i) == conflict)
        projectErrorsAC.removeItemAt(i);
}               
}

for some reason, this isn't working...

* EDIT *

SUCCESS!

I had to create a module to put inside the repeater - the repeater now looks like this:

<mx:Repeater id="projRP" width="100%" dataProvider="{projectErrorsAC}">
    <conflict:showErrors id="projErrors" thisObject="{projRP.currentItem}" isProject="true"/>
</mx:Repeater>

and my module looks like this:

<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init();">
        <mx:Script>
            <![CDATA[
                public var isProject:Boolean;
                public var thisObject:Object;
                [Bindable] public var displayString:String = new String;

                private function init():void
                {
                    if (isProject)
                    {
                        displayString = thisObject.student + " is working on the following projects on the same day: " + thisObject.proj1name + " and " + thisObject.proj2name + ".";
                    }
                }
            ]]>
        </mx:Script>

    <mx:Canvas width="750">
        <mx:HBox>
            <mx:Text id="projmsg" text="{displayString}" />
            <mx:Text id="allow" text="Allow" color="#ff0000" selectable="false" click="parentDocument.acceptProjConflict(thisObject)" mouseOver="parentApplication.switchCursor(true);" mouseOut="parentApplication.switchCursor(false);" />
            <mx:Text text=" |" />
            <mx:Text id="decline" text="Decline" color="#ff0000" selectable="false" click="parentDocument.declineProjConflict(thisObject);" mouseOver="parentApplication.switchCursor(true);" mouseOut="parentApplication.switchCursor(false);" />
        </mx:HBox>
    </mx:Canvas>
</mx:Module>

Solution

  • This could be an ArrayCollection specific issue that is being caused because it might occur that you are trying to remove an object that is no longer at the index you think it might be. I believe this kind of problem is exactly why Java advises the use of collection iterators.

    Further explanation here

    Furthermore, I would advise you to use List with an itemRenderer instead of a repeater. Repeaters are known for their ability to cause memory leaks and are not as optimized as a List with itemRenderers.

    Cheers