Lorsque vous utiliser un dataProvider dans un composant Flex d'affichage de data (DataGrid, List, Tree, ...), vous pouvez utiliser plusieurs types de dataProvider (XMLList, ArrayCollection par exemple) qui seront ensuite convertis par derrière par Flex pour qu'il puisse effectuer ses opérations et afficher la data. De base, toute votre donnée sera affichée, ou tout du moins celle qui peut être affichée dans une liste par exemple.
Quand vous aurez beaucoup de data, vous voudrez souvent la filtrer selon un critère. Par exemple, laisser l'utilisateur taper le nom qu'il cherche et n'afficher que la data contenant ce texte. Pour cela, il faut utiliser une filterFunction. Celle-ci va être appelée par Flex automatiquement pour chaque élément pour savoir si la data doit être affichée ou non.
La signature d'une filterFunction est simple, elle prend un item de type Object en argument et renvoie un Boolean (true ou false donc). Flex va donc passer tous les objets du dataProvider dans cette fonction et suivant le Boolean retourné par la fonction, il va l'afficher ou non. Voici la tête d'une filterFunction:
public function myFilterFunction(item:Object):Boolean{
// ...vérifications sur item
return true ou false suivant si on veux afficher ce résultat;
}
Seulement, si vous essayez avec un Tree, vous verrez que cela ne fonctionne pas. Le filtre est seulement appliqué aux nœuds de plus haut niveau de la collection, il n'est pas appliqué de manière récursive sur les nœuds enfants.
Ce bug est un bug connu du Flex SDK: filterFunction for XMLListCollection is invoked only on root node of hierarchical data. Il avait été prévu de le corriger pour un éventuel Flex 3.4 puis il a été retiré. Certains ont donc trouvé de bonne solutions pour contourner ce problème, voici son explication.
Lorsqu'il fait le rendu de ses noeuds, un objet Tree s'aide d'une classe qui implémente soit l'interface ITreeDataDescriptor, soit l'interface ITreeDataDescriptor2. Par défaut, c'est une instance de DefaultDataDescriptor qui s'en charge mais on peut en utiliser une autre pour garnir le Tree avec une implémentation différente. En surchargeant le data descriptor du Tree avec une classe qui supporte le filtrage, le contenu du tree pourra facilement être filtré.
Voici un exemple d'application qui devient possible avec cette modification. Cochez/Décochez les checkbox pour filtrer l'arbre de gauche.
Flex Source Code Download: Télécharger le code source complet de l'application
Vous pouvez télécharger les sources de cet exemple pour analyser son fonctionnement. L'auteur explique que le mx:Tree appelle la méthode getChildren() du data descriptor pour chaque nœud. Cette fonction de filtre assez similaire à la filterFunction dont on parlait plus haut peut être appellée et va renvoyer les enfants qu'ils faut afficher.
Il faut noter qu'il précise que son implémentation du ITreeDataDescriptor est loin d'être complète et qu'il a simplement implémenté ce dont il avait besoin pour faire ce qu'il voulait. Rien que le DefaultDataDescriptor est bien plus complexe et implémente toutes les méthodes avec des mécanismes de cache, etc...
Voir l'article de l'auteur original
Autres Tutoriaux Flex liés:
- Flex ArrayCollection – FilterFunction avec plusieurs functions (Comparatif de 5 méthodes)
- Flex 4 – (2) Création de composants Flex ré-utilisables, les meilleures techniques
- Flex Tree – Peupler un Tree avec un dataProvider XML et Array (en MXML et ActionScript)
- Flex AdvancedDataGrid – Utiliser groupIconFunction pour déterminer l'icon d'un Tree
- Flex AdvancedDataGrid – Icônes et labels du Tree de navigation









Perso, je trouve pas que c'est un bug.. d'ailleurs je suis sur que si cela avait été le cas tout le monde aurait râlé et ça aurait été un bug
Pour mes tree, j'utilise souvent des données Flat directement , par exemple des objets comme
que je mets dans une ICollectionView pour appliquer un filtre proprement d'une part, puis j'utilise un dataDescriptor pour montrer les data filtrées.
Il en effet assez rare d'avoir les données déjà en hiérarchie, surtout venant d'une base SQL. Restons MVC, chacun à sa place!