Recentemente precisei criar um script que recebesse um array de valores e selecionasse todos os itens de uma Tree cujo labelField fosse igual a algum dos elementos do array, após ter muito trabalho para montar tal script resolvi extender a Tree e deixar o script ainda mais maleável incluindo a possibilidade de procurar por outras propriedades dos itens além do labelField e até mesmo passar uma função para ser usada para decidir se o item deve ser selecionado.
Segue o código que eu criei, com certeza ele pode ser melhorado e otimizado portanto se alguem tiver alguma dica por favor poste um comentário.
package com.wordpress.bobfernandes
{
import mx.collections.ArrayCollection;
import mx.controls.Tree;
import mx.events.FlexEvent;[Bindable]
public class AdvancedTree extends Tree
{
private var i:int;
private var indice:int//esse ArrayCollection será usado como dataProvider da Tree
private var _dados:ArrayCollection = new ArrayCollection();public function AdvancedTree()
{
super();
addEventListener(FlexEvent.CREATION_COMPLETE, init);
}
private function init(event:FlexEvent):void
{
dataProvider = _dados;
}
//função set usada para garantir o refresh e a atualização da tree
public function set dados(value:ArrayCollection):void
{
_dados = value;
_dados.refresh();
dataProvider = _dados;
}
public function get dados():ArrayCollection
{
return _dados;
}// método público que seleciona itens por label
// recebe um array de valores a serem procurados
public function selecionarPorLabel(valuesToFind:Array):void
{
selecionarPorPropriedade(valuesToFind, labelField);
}// é esse método que possibilita procurar
// por outra propriedade diferente da definida no labelField
// e também passar uma função para ser usada na decisão da seleção
public function selecionarPorPropriedade(valuesToFind:Array, prop:String, funcao:Function = null):void
{
// Limpa a lista de indices selecionados
selectedIndices = new Array();
// Seta o início para zero
indice = 0;
if(funcao == null)
{
// se nenhuma função for passada usa a comparar()
funcao = comparar;
}
// é necessário expandir toda a árvore
// pois o índice de um item varia se
// os itens anteriores estão abertos ou não
expandAll();
selectItems(valuesToFind, dados, prop, funcao);
}
// função auxiliar para adicionar um determinado indice
// a lista de índices selecionados
private function adicionaIndexAosSelecionados(value:int):void
{
// um push no selectedIndices não funciona
// pois o processamento é feito na função set
// por isso temos que setar o selectedIndices
var arr:Array = new Array();
if(selectedIndices != null)
{
// guarda o selectedIndices atual
arr = selectedIndices;
}
// adiciona o valor
arr.push(value);
// seta o selectedIndices para a nova array
selectedIndices = arr;
}
// função básica para usar como comparação
private function comparar(item:Object, stringToCompare:String, propriedade:String):Boolean
{
var retorno:Boolean = false;
if(item[propriedade] != null)
{
if(item[propriedade].toString() == stringToCompare.toString())
{
retorno = true;
}
}
return retorno;
}
// função para expandir todos os nós da Tree
private function expandAll():void
{
for(i = 0; i < dados.length; i++)
{
expandItem(dados[i], true, true);
expandChildrenOf(dados[i], true);
}
}
// função recursiva que varre a Tree
private function selectItems(valuesToFind:Array, collection:ArrayCollection, propToCompare:String, compareFunction:Function):void
{
for(var k:int = 0; k < collection.length; k++)
{
for(i = 0; i < valuesToFind.length; i++)
{
var linha:String = valuesToFind[i];
if(compareFunction(collection[k], linha, propToCompare))
{
adicionaIndexAosSelecionados(indice);
}
}
indice++;
// lembre-se que para usar um arrayCollection como dataProvider
// as propriedades que tem filhos devem obrigatóriamente se chamar “children”
var Children:ArrayCollection = collection[k].children as ArrayCollection;
if(Children != null)
{
selectItems(valuesToFind, Children, propToCompare, compareFunction);
}
}
}
}
}
Na hora de usar o componente faça como um Tree normal a única diferença é que ao invés de setar a propriedade dataProvider diretamente sete a propriedade dados:
<utils:AdvancedTree
id=”idDaTree”
labelField=”propiedadeParaUsarComoLabel”
dados=”{seuArrayCollection}”
width=”100%” height=”100%”
allowMultipleSelection=”true”
/>
Para fazer a seleção use algo como:
idDaTree.selecionarPorLabel(arrayDeValoresASeremSelecionados);