DataGrid - 根据自己的值对列进行排序,其次基于其他列值?

时间:2013-08-26 14:16:28

标签: actionscript-3 flex flex4 flex3

我有一个包含两列的AdvancedDatagrid:Code(字符串)和Value(数字)。我对每列使用相同的排序函数。我想要做的是根据Value列(数字数据)对两列进行排序,但是如果没有可用的数字,我希望按字母顺序为Code列进行排序。

我通过一个例子来简化我面临的问题,以表示我想要做的事情:

图片显示了两列,根据Value列对两列进行了排序。 在值为NaN的情况下,我希望按字母顺序对“代码”列值进行排序。因此,一,二,三,四将保持不变,但是BADC将是ABCD。

enter image description here

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
                layout="absolute" minWidth="955" minHeight="600" initialize="initializeHandler(event)">

    <mx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.events.FlexEvent;
            import mx.utils.ObjectUtil;

            [Bindable]
            private var ac:ArrayCollection;

            protected function initializeHandler(event:FlexEvent):void
            {
                ac = new ArrayCollection();

                var one:NameValueObject = new NameValueObject("One", 1);
                var two:NameValueObject = new NameValueObject("Two", 2);
                var three:NameValueObject = new NameValueObject("Three", 3);
                var four:NameValueObject = new NameValueObject("Four", 4);
                var a:NameValueObject = new NameValueObject("A", NaN);
                var b:NameValueObject = new NameValueObject("B", NaN);
                var c:NameValueObject = new NameValueObject("C", NaN);
                var d:NameValueObject = new NameValueObject("D", NaN);

                ac.addItem(one);
                ac.addItem(two);
                ac.addItem(three);
                ac.addItem(four);
                ac.addItem(b);
                ac.addItem(a);
                ac.addItem(d);
                ac.addItem(c);              
            }

            private function numericValueSort(obj1:Object, obj2:Object):int
            {
                var value1:Number = (obj1 as NameValueObject).value;
                var value2:Number = (obj2 as NameValueObject).value;

                return ObjectUtil.numericCompare(value1, value2);
            }

            private function codeLabelFunction(item:Object, column:AdvancedDataGridColumn):String
            {
                return (item as NameValueObject).code;
            }

        ]]>
    </mx:Script>

    <mx:AdvancedDataGrid width="500" height="300" dataProvider="{ac}">
        <mx:columns>
            <mx:AdvancedDataGridColumn id="codeColumn" 
                                       headerText="Code"
                                       dataField="value"
                                       labelFunction="codeLabelFunction"
                                       sortCompareFunction="numericValueSort">

            </mx:AdvancedDataGridColumn>
            <mx:AdvancedDataGridColumn id="numericValueColumn" 
                                       headerText="Value"
                                       dataField="value"
                                       sortCompareFunction="numericValueSort">

            </mx:AdvancedDataGridColumn>
        </mx:columns>
    </mx:AdvancedDataGrid>
</mx:Application>

NaveValueObject类

package
{
    public class NameValueObject
    {
        public var code:String;
        public var value:Number;

        public function NameValueObject(aCode:String, aNumber:Number)
        {
            code = aCode;
            value = aNumber;
        }
    }
}

4 个答案:

答案 0 :(得分:1)

试试这个:

private function numericValueSort(obj1:Object, obj2:Object):int
{
    var o1:NameValueObject = obj1 as NameValueObject;
    var o2:NameValueObject = obj2 as NameValueObject;

    var ret:int = 0;
    if (isNaN(o1.value) || isNaN(o2.value)) {
        if (o1.code > o2.code) {
            ret = 1;
        } else if (o1.code < o2.code){
            ret = -1;
        }
    } else {
        ret = ObjectUtil.numericCompare(o1.value, o2.value);
    }
    return ret;
}

您的功能流程编号要么被重视,要么在两个对象的代码字段之间进行比较

答案 1 :(得分:0)

以下比较功能将优先考虑数值并根据代码对NaN值进行排序。方法是为每个对象组成一个新字符串,并在字符串前面加上一个表示优先级的值(A> B):

private function numericValueSort(obj1:NameValueObject, obj2:NameValueObject):int {
  var a:String = (isNaN(obj1.value) ? "B" : "A") + obj1.value + obj1.code;
  var b:String = (isNaN(obj2.value) ? "B" : "A") + obj2.value + obj2.code;
  return ObjectUtil.stringCompare(a, b);
}

请注意,例如,在排序1,2,11时,这可能会产生奇怪的结果。在这种情况下,您最好使用natural compare。 AS3Commons Lang库中提供了一个ActionScript实现。

答案 2 :(得分:0)

我想通了,这是我最终使用的sortCompareFunction:

它检查值/ s无效的3种可能条件。 如果唯一的一个是NaN,则返回1或-1,否则进行基于的排序 代码栏。

然后,如果两个值都有效(不是NaN),则进行比较:

private function numericValueSort(obj1:Object, obj2:Object):int
{
    var o1:NameValueObject = obj1 as NameValueObject;
    var o2:NameValueObject = obj2 as NameValueObject;

    if( isNaN(o1.value) && !isNaN(o2.value) ){
        return 1; // o1 appears after o2;
    }
    if( !isNaN(o1.value) && isNaN(o2.value) ){
        return -1; // o1 appears before o2
    }
    if( isNaN(o1.value) && isNaN(o2.value) ){
            // Both values are NaN, so they will have been placed 
            // at the end when compared with valid values (from previous two 
            // IF statements, but now to compare to each other, we sort using the 
            // code field
        return ObjectUtil.stringCompare(o1.code, o2.code);
    }
    // If neither value is NaN, then do a regular numeric compare
    return ObjectUtil.numericCompare(o1.value, o2.value);
}

enter image description here

答案 3 :(得分:0)

我希望所有的NaN值都在底部,而不管排序如何。除了Nan值之外,它应该被排序(将所有NaN值保持在底部)?