Merge data into filtered ArrayCollection (maybe by using IViewCursor or localIndex?)

后端 未结 1 737
南旧
南旧 2021-01-16 07:44

I have a Flex question, which isn\'t as easy as it seems at first.

At least I\'m struggling since 1 week with it.

I have prepared a test case and a screensho

相关标签:
1条回答
  • 2021-01-16 08:08

    Try to operate ArrayCollection's source property the following way:

    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark">
    
        <fx:Declarations>
            <s:RadioButtonGroup id="filterGroup" change="radioClicked(event)" />
        </fx:Declarations>
    
        <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
    
            private const DATA1:Array = [ 10, 20, 30, 40, 50 ];
            private const DATA2:Array = [ 10, 20, 30, 50 ];
            private const DATA3:Array = [ 10, 20, 30, 40, 50, 60 ];
            private const DATA4:Array = [ 10, 20, 30, 35, 40, 50 ];
            private const DATA5:Array = [];
            private const DATA6:Array = [ 25, 45 ];
    
            [Bindable]
            private var _data:ArrayCollection = new ArrayCollection();
    
            private function filterEven(item:Object):Boolean
            {
                var i:uint = item as uint;
                return (i % 2 == 0);
            }
    
            private function filterOdd(item:Object):Boolean
            {
                var i:uint = item as uint;
                return (i % 2 == 1);
            }
    
            private function merge(data:Array):void
            {
                var i:int;
                var j:int;
    
    
                var sourceData:Array = _data.source;
                // 1) remove items missing in data from _data
                found1: for (i = sourceData.length - 1; i >= 0; i--)
                {
                    for (j = data.length - 1; j >= 0; j--)
                    {
                        if (sourceData[i] == data[j])
                            continue found1;
                    }
                    var index:int = _data.getItemIndex(sourceData[i]);
                    if (index > -1)
                        _data.removeItemAt(index); // remove visible items
                    else
                        sourceData.splice(i, 1); // remove hidden (filtered) items
                }
    
                // 2) add items appeared in data to _data
                found2: for (j = 0; j < data.length; j++)
                {
                    for (i = 0; i < sourceData.length; i++)
                    {
                        if (sourceData[i] == data[j])
                            continue found2;
                    }
                    _data.addItem(data[j]);
                }
            }
    
            private function radioClicked(event:Event):void
            {
                switch (filterGroup.selection)
                {
                    case allButton:
                    {
                        _data.filterFunction = null;
                        break;
                    }
                    case oddButton:
                    {
                        _data.filterFunction = filterOdd;
                        break;
                    }
                    case evenButton:
                    {
                        _data.filterFunction = filterEven;
                        break;
                    }
                }
                _data.refresh();
            }
        ]]>
        </fx:Script>
    
        <s:layout>
            <s:VerticalLayout gap="20" />
        </s:layout>
    
        <s:HGroup verticalAlign="baseline">
            <s:Label text="FILTER:" />
            <s:RadioButton id="allButton" group="{filterGroup}" label="All" selected="true" />
            <s:RadioButton id="oddButton" group="{filterGroup}" label="Odd" />
            <s:RadioButton id="evenButton" group="{filterGroup}" label="Even" />
        </s:HGroup>
    
        <s:List dataProvider="{_data}" id="_list" />
    
        <s:Button click="merge(DATA1)" id="_btn1" label="{DATA1.join()}" />
        <s:Button click="merge(DATA2)" id="_btn2" label="{DATA2.join()}" />
        <s:Button click="merge(DATA3)" id="_btn3" label="{DATA3.join()}" />
        <s:Button click="merge(DATA4)" id="_btn4" label="{DATA4.join()}" />
        <s:Button click="merge(DATA5)" id="_btn5" label="{DATA5.join()}" />
        <s:Button click="merge(DATA6)" id="_btn6" label="{DATA6.join()}" />
    
    </s:Application>
    

    And a couple of advices on using RadioButton and RadioButtonGroup:

    • Do not use click events to handle changes. This disables possibility to manage buttons other way (from keyboard for example). Use change instead.
    • If you are using RadioButtonGroup it is better to refer group rather than groupName. It gives you possibility to check problems on compile time (imagine some misprints in group name).
    • Do not check selected button against label. You can misprint label name or you can change label etc. and compiler can't help you in that.
    0 讨论(0)
提交回复
热议问题