2013-08-06 1 views
0

J'essaie de trier une collection XMLListCollection en fonction des attributs d'un autre XMLListCollection et je n'ai pas beaucoup de succès.Tri d'une XMLLIstCollection à l'aide de la fonction de comparaison

Je voudrais trier une collection de nourriture dans l'ordre dans lequel elle a été mangée - qui est stockée dans une autre collection XMLList.

<?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',[email protected]); 
      var _currentFruitIndex:int= getNodeIndexByAttribute(_foodCollection,'id',[email protected]) 

      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> 

me semble être tout en train de faire autant que je peux voir, mais je dois faire quelque chose de mal comme il ne fonctionne pas! Je pense que cela peut avoir quelque chose à voir avec la façon dont j'ai implémenté la fonction de comparaison.

Une aide avec ceci serait grandement appréciée!

Répondre

1

En définissant une fonction de tri, le XMLListCollection ne sera pas trié par défaut. Vous devez refresh() la collection à un moment donné, cela peut être fait automatiquement lorsque vous avez terminé le chargement de la vue, ou à la demande. J'ai ajouté un bouton pour illustrer le point.

Si vous testez ce bouton que j'ai ajouté, cela devrait fonctionner. De plus, j'ai remplacé s: tri par mx parce que je suis sur un ancien framework Flex, alors n'hésitez pas à le changer à nouveau.

<?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', [email protected]); 
     var _currentFruitIndex:int = getNodeIndexByAttribute(_foodCollection, 'id', [email protected]) 

     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> 
+0

Salut bitoiu, merci d'avoir jeté un oeil. Les bonnes nouvelles sont que certains tri se produit, mais les mauvaises nouvelles sont que le tri est dans le mauvais ordre. Dans l'exemple, le résultat attendu est C, A, D, B, mais le résultat actuel est C, B, A, D. D'autres idées? – Beaker

+0

À ce stade, vous devez déboguer le code de tri, je crois que j'ai répondu à votre question comme pourquoi le tri n'est pas arrivé en premier lieu. Si vous arrêtez la fonction de comparaison, il devrait être évident que le résultat n'est pas le résultat escompté. Veuillez marquer la question comme ayant été répondue sur mon post précédent, si vous pensez que je vous ai aidé à déterminer pourquoi le tri ne se faisait pas. – bitoiu

+0

Salut bitoiu, Si je pouvais vous donner le crédit pour prendre le temps de regarder, je le ferais, mais malheureusement, je ne peux pas répondre à cette question comme elle ne l'est pas. Le problème est de trier une collection de nourriture dans l'ordre dans lequel elle a été mangée. L'actualisation était utile dans cet exemple (mon code actuel contient déjà une actualisation) mais j'ai déjà mentionné que je pense que le problème réside dans la façon dont j'implémente la fonction de comparaison. Déboguer à travers la fonction de comparaison me montre qu'il retourne de bonnes données (-1 pour descendre, 0 pour rester et 1 pour monter) mais les éléments ne se trient pas correctement. – Beaker

Questions connexes