Flex:排序 - 编写自定义compareFunction?

时间:2009-09-02 14:42:13

标签: flex sorting

好的,我按字母顺序对XMLListCollection进行排序。我有一个问题。如果值为“ALL”,我希望它在列表中排在第一位。在大多数情况下,这种情况已经发生,但数字值正在“ALL”之前进行排序。我希望“ALL”始终是我的dataProvider中的第一个选择,然后按字母顺序排列。

所以我正在尝试编写自己的排序函数。有没有办法可以检查其中一个值是否全部,如果没有告诉它对值进行常规比较?

这就是我所拥有的:

function myCompare(a:Object, b:Object, fields:Array = null):int
{
    if(String(a).toLowerCase() == 'all')
    {
        return -1;
    }
    else 
        if(String(b).toLowerCase() == 'all')
        {
            return 1;
        }
    // NEED to return default comparison results here?
}

//------------------------------

var sort:Sort = new Sort();
sort.compareFunction = myCompare;

我正在尝试做什么解决方案?

4 个答案:

答案 0 :(得分:14)

来自John Isaacks的解决方案很棒,但是他忘记了“fields”变量,他的例子不适用于更复杂的对象(除了字符串)

示例:

// collection with custom objects. We want to sort them on "value" property
// var item:CustomObject = new CustomObject();
// item.name = 'Test';
// item.value = 'Simple Value';

var collection:ArrayCollection = new ArrayCollection();
var s:Sort = new Sort();
s.fields = [new SortField("value")];
s.compareFunction = myCompare;
collection.sort = s;
collection.refresh();

private function myCompare(a:Object, b:Object, fields:Array = null):int
{
    if(String((a as CustomObject).value).toLowerCase() == 'all')
    {
        return -1;
    }
    else if(String((b as CustomObject).value).toLowerCase() == 'all')
    {
        return 1;
    }
    // NEED to return default comparison results here?
    var s:Sort = new Sort();
    s.fields = fields;
    var f:Function = s.compareFunction;
    return f.call(null,a,b,fields);
}

答案 1 :(得分:8)

嗯,我尝试了一些东西,我真的很惊讶它实际上有效,但这就是我做的。

Sort类有一个名为internalCompare的私有函数。由于它是私人的,你不能称之为。但是有一个名为compareFunction的getter函数,如果没有定义compare函数,则返回对internalCompare函数的引用。所以我做的是得到这个引用,然后调用它。

private function myCompare(a:Object, b:Object, fields:Array = null):int
{
    if(String(a).toLowerCase() == 'all')
    {
        return -1;
    }
    else if(String(b).toLowerCase() == 'all')
    {
        return 1;
    }
    // NEED to return default comparison results here?
    var s:Sort = new Sort();
    var f:Function = s.compareFunction;
    return f.call(null,a,b,fields);
}

答案 2 :(得分:0)

谢谢你们,这对我们有很大的帮助。在我们的例子中,我们需要底部的所有空行(在DataGrid中)。应该正常排序所有非空行。我们的行数据都是动态对象(从JSON转换而来) - 对ValidationHelper.hasData()的调用只是检查行是否为空。由于某种原因,字段有时包含dataField String值而不是SortFields,因此在设置'fields'属性之前进行检查:

private function compareEmptyAlwaysLast(a:Object, b:Object, fields:Array = null):int {
    var result:int;
    if (!ValidationHelper.hasData(a)) {
        result = 1;
    } else if (!ValidationHelper.hasData(b)) {
        result = -1;
    } else {
        if (fields && fields.length > 0 && fields[0] is SortField) {
            STATIC_SORT.fields = fields;
        }
        var f:Function = STATIC_SORT.compareFunction;
        result = f.call(null,a,b,fields);
    }
    return result;
}

答案 3 :(得分:-1)

我没有找到适合我的情况的这些方法,即按字母顺序排列字符串列表,然后在列表末尾附加“创建新...”项。

我处理事物的方式有点不雅,但可靠。

我使用alpha排序对我的ArrayCollection字符串(名为 orgNameList )进行了排序,如下所示:

    var alphaSort:Sort = new Sort();
    alphaSort.fields = [new SortField(null, true)];
    orgNameList.sort = alphaSort;
    orgNameList.refresh();

然后我将已排序列表的元素复制到一个名为 customerDataList 的新ArrayCollection中。结果是新的ArrayCollection元素按字母顺序排列,但不受Sort对象的影响。因此,添加新元素会将其添加到ArrayCollection的末尾。同样,将项目添加到ArrayCollection中的特定索引也将按预期工作。

    for each(var org:String in orgNameList)
    {
        customerDataList.addItem(org);
    }

然后我就加入了“创建新...”项目,如下所示:

    if(userIsAllowedToCreateNewCustomer) 
    {
        customerDataList.addItem(CREATE_NEW);
        customerDataList.refresh();
    }