0

我正在尝试根据另一个 XMLListCollection 的属性对 XMLListCollection 进行排序,但没有取得多大成功。

我想将一组食物按食用顺序排序 - 存储在另一个 XMLListcollection 中。

<?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" 
xmlns:mx="library://ns.adobe.com/flex/mx" 
minWidth="955" minHeight="600">
<fx:Declarations>
    <fx:XML xmlns="" id="_foods">
        <data>
            <node label="Apple" id="A"/>
            <node label="Banana" id="B"/>
            <node label="Carrot" id="C"/>
            <node label="Dandelion" id="D"/>
        </data>
    </fx:XML>
    <fx:XML xmlns="" id="_orders">
        <data>
            <order  id="C"/>
            <order  id="A"/>
            <order  id="D"/>
            <order  id="B"/>
        </data>
    </fx:XML>
    <s:XMLListCollection id="_orderList" source=" {_orders.children()}"/>
    <s:XMLListCollection id="_foodCollection"   source="{_foods.children()}" sort="{_foodSort}"/>
    <s:Sort id="_foodSort" compareFunction="sortFruits"/>
</fx:Declarations>
<fx:Script>
    <![CDATA[

        protected function sortFruits(a:Object, b:Object, fields:Array = null):int
        {
         var _currentItem:XML = XML(a);
         var _currentOrderIndex:int= getNodeIndexByAttribute(_orderList,'id',_currentItem.@id);
            var _currentFruitIndex:int= getNodeIndexByAttribute(_foodCollection,'id',_currentItem.@id)

            if(_currentFruitIndex > _currentOrderIndex) {_returnData =1;}
            else 
            if(_currentFruitIndex < _currentOrderIndex) { _returnData =-1;}
            else {_returnData = 0}

            var _returnData:int = 0
                return _returnData
        }

        public function getNodeIndexByAttribute(theCollection:XMLListCollection,theAttributeName:String, theAttributeValue:String):int { 
            //THIS IS RETURNS THE INDEX OF A CHILD NODE BASED UPON AN ATTRIBUTE THAT IS PASSED IN - GENERIC FUNCTION
            var _returnData:int 

            for (var i:int = 0; i < theCollection.length; i++) 
            {
                var _currentItem:XML = theCollection.getItemAt(i) as XML
                if (_currentItem.attribute(theAttributeName) == theAttributeValue)  { _returnData = i;
        break;
                }

            }


            return _returnData;
        } 
    ]]>
</fx:Script>
<s:List width="100%" height="100%" labelField="@label" dataProvider="{_foodCollection}"/>
</s:Application>

据我所知,我似乎做的一切都是正确的,但我一定做错了什么,因为它不起作用!我认为这可能与我实现比较功能的方式有关。

对此的任何帮助将不胜感激!;)

4

1 回答 1

1

通过定义排序函数,XMLListCollection 默认不会被排序。您需要在某个时候刷新()集合,这可以在您完成加载视图时自动完成,或者按需完成。我添加了一个按钮来说明这一点。

如果您测试我添加的这个按钮,它应该可以工作。另外,我已经用 mx 替换了 s:sort,因为我使用的是较旧的 Flex 框架,所以请随时再次更改它。

<?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"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    >

<s:layout>
    <s:VerticalLayout />
</s:layout>

<fx:Declarations>

    <mx:Sort id="sort" compareFunction="sortFruits" />

    <fx:XML xmlns="" id="_foods">
        <data>
            <node label="Apple" id="A"/>
            <node label="Banana" id="B"/>
            <node label="Carrot" id="C"/>
            <node label="Dandelion" id="D"/>
        </data>
    </fx:XML>
    <fx:XML xmlns="" id="_orders">
        <data>
            <order id="C"/>
            <order id="A"/>
            <order id="D"/>
            <order id="B"/>
        </data>
    </fx:XML>
    <s:XMLListCollection id="_orderList" source=" {_orders.children()}"/>
    <s:XMLListCollection id="_foodCollection" source="{_foods.children()}" sort="{sort}"/>
</fx:Declarations>


<fx:Script>
<![CDATA[
    protected function sortFruits(a:Object, b:Object, fields:Array = null):int {
        var _currentItem:XML = XML(a);
        var _currentOrderIndex:int = getNodeIndexByAttribute(_orderList, 'id', _currentItem.@id);
        var _currentFruitIndex:int = getNodeIndexByAttribute(_foodCollection, 'id', _currentItem.@id)

        if (_currentFruitIndex > _currentOrderIndex) {
            _returnData = 1;
        }
        else if (_currentFruitIndex < _currentOrderIndex) {
            _returnData = -1;
        }
        else {
            _returnData = 0
        }

        var _returnData:int = 0
        return _returnData
    }

    public function getNodeIndexByAttribute(theCollection:XMLListCollection, theAttributeName:String, theAttributeValue:String):int {
        //THIS IS RETURNS THE INDEX OF A CHILD NODE BASED UPON AN ATTRIBUTE THAT IS PASSED IN - GENERIC FUNCTION
        var _returnData:int

        for (var i:int = 0; i < theCollection.length; i++) {
            var _currentItem:XML = theCollection.getItemAt(i) as XML
            if (_currentItem.attribute(theAttributeName) == theAttributeValue) {
                _returnData = i;
                break;
            }

        }


        return _returnData;
    }
    ]]>
</fx:Script>
    <s:List width="100%" labelField="@label" dataProvider="{_foodCollection}"/>
    <s:Button label="Sort me" click="_foodCollection.refresh()" />
</s:Application>
于 2013-08-06T17:20:33.697 回答