Flex 3: удаление элементов из коллекции массивов, когда пользователь нажимает кнопку, и отражение этого в репитере - PullRequest
1 голос
/ 18 мая 2011

У меня есть arrayCollection со следующей структурой:

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

AC определяется следующим образом:

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

Я использую этот AC в ретрансляторе для отображения каждой ошибки. После отображения каждой ошибки я разместил кнопки «Принять» и «Запретить». Как только пользователь нажмет одну из этих кнопок, я бы хотел вызвать функцию, которая удаляет конкретную ошибку из AC. Вот что у меня есть:

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>

и вот функция, которую я вызываю в части «щелчка»:

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>

Ответы [ 3 ]

0 голосов
/ 18 мая 2011

Во-первых, вы пробовали отладку?

Во-вторых, я удивлен, что обработчик щелчков работает, потому что у 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;
       }
   }         
}

Но да, конечно, ваша проблема заключается в том, что ваш обработчик никогда не вызывается.

0 голосов
/ 03 сентября 2013

Вы можете использовать

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

вместо

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

Это будет быстрее, если у вас большие данные.

0 голосов
/ 18 мая 2011

Это может быть специфическая проблема ArrayCollection, которая вызывается, потому что может случиться, что вы пытаетесь удалить объект, который больше не находится в том индексе, который, как вы думаете, может быть.Я считаю, что именно из-за такого рода проблем Java рекомендует использовать итераторы коллекций.

Дальнейшее объяснение здесь

Более того, я бы посоветовал вам использовать List с itemRendererвместо повторителя.Повторители известны своей способностью вызывать утечки памяти и не так оптимизированы, как список с itemRenderers.

Cheers

...