开发者

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="{projectEr开发者_如何学CrorsAC}">
<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>


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


First, have you tried debugging?

Second, I'm surprised the click handler works because Repeater has weird scoping issues (which normally fails silently), which is why I said you should try to debug.

Third, your click handler is inefficient, you should do something like this instead:

public function acceptProjConflict(conflict:Object):void
{
   for(var i:uint, len:uint = projectErrorsAC.length; i<len; i++)
   {
       if(projectErrorsAC.source[i] == conflict)
       {
           projectErrorsAC.removeItemAt(i);
           break;
       }
   }         
}

But yeah, fairly sure your problem lies with the fact that your handler is never called.


You might use

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

instead of

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

It will be faster when you have large data.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜