Flex 3:当用户单击按钮时从数组集合中删除项目,并将其反映在转发器中



>我有一个具有以下结构的arrayCollection:

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

AC 的定义如下:

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

我在中继器中使用此交流电来显示每个错误。 显示每个错误后,我放置了一个"接受"和"拒绝"按钮。 用户单击这些按钮中的任何一个后,我想调用一个函数来从 AC 中删除特定错误。 这是我到目前为止所拥有的:

中继 器:

<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>

这是我在"点击"部分中调用的函数:

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

由于某种原因,这不起作用...

*编辑*

成功!

我必须创建一个模块放在中继器中 - 中继器现在看起来像这样:

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

我的模块看起来像这样:

<?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>
这可能是导致

ArrayCollection 的特定问题,因为您可能会尝试删除不再位于您认为可能的索引处的对象。我相信这种问题正是Java建议使用集合迭代器的原因。

进一步解释在这里

此外,我建议您将List与itemRenderer一起使用,而不是中继器。中继器以其导致内存泄漏的能力而闻名,并且不像带有 itemRenderers 的列表那样优化。

干杯

首先,你试过调试吗?

其次,我很惊讶点击处理程序的工作原理,因为 Repeater 存在奇怪的范围问题(通常会静默失败),这就是为什么我说你应该尝试调试。

第三,你的点击处理程序效率低下,你应该做这样的事情:

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;
       }
   }         
}

但是,是的,相当确定您的问题在于您的处理程序从未被调用过。

你可以使用

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

而不是

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

当您拥有大量数据时,它会更快。

最新更新