4 Agosto, 2008 às 2:13 pm (Componentes, Flex)
Tags: ArrayCollection, Componentes, Flex, tree
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);
2 Comentários
29 Julho, 2008 às 6:54 pm (Flex, Soap)
Tags: Bug, Erro, Fault, Flex, Soap
Atualmente estou trabalhando em um projeto com uma arquitetura que inclui um servidor BEA Aqualogic e nos deparamos com um problema que parecia ser bem severo: O flex não conseguia enxergar um SOAPError gerado pelo ServiceBus, isso é um bug reportado no bug track da Adobe, nas pesquisas que fizemos as únicas soluções envolviam utilizar ou BlazeDS ou LCDS que no nosso caso eram soluções inaceitáveis (por conta de regras e arquiteturas definidas pelo cliente).
Após um brainstorm com nosso arquiteto e o pessoal dos dataServices e webServices chegamos a conclusão de que isso na verdade não é um erro ou bug do flex pois o header padrão para um erro de SOAP é 500 que é um http error, portanto a solução foi alterar no ServiceBus o gerenciamento de erro para que ao invés de disparar um erro com header 500 disparar um erro com header 200 e voilá o flex recebeu o erro como um SOAPError e as mensagens de erro geradas pelo dataService chegaram bonitinhas no Flex.
Fica aí a dica de como fazer para receber um SOAPError no flex.
Deixe um comentário
10 Junho, 2008 às 2:28 am (Componentes, Flex)
Tags: ActionScrpt, AdvancedDataGrid, Componentes, Flex, HierarchicalData
Esse é o segundo post da série sobre AdvancedDataGrid no primeiro post eu dei uma dica bem útil para quem quer utilizar o hierarchicalData com dados vindos de um RemoteObject.
O componente HierarchicalData não tem um método refres(), para conseguir essa função é necessário extender a classe HierarchicalData, eis o código:
package com.wordpress.bobfernandes.beans
{
import mx.collections.HierarchicalData;
import mx.events.CollectionEvent;
import mx.events.CollectionEventKind;
public class RefreshHieararchicalData extends HierarchicalData
{
// O truque é sobrescrever o set source
// para que seja disparado um CollectionEvent do tipo reset
override public function set source(value:Object):void
{
super.source = value;
var event:CollectionEvent = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
event.kind = CollectionEventKind.RESET;
dispatchEvent(event);
}
}
}
Na hora de usar faça assim:
<mx:dataProvider>
<beans:RefreshHieararchicalData id=”UmIdRelevante” source=”{SeuArrayCollection}”/>
</mx:dataProvider>
No próximo post eu mostrarei um exemplo de ADG com ItemRenderer.
5 Comentários
10 Junho, 2008 às 1:48 am (Componentes, Flex)
Tags: ActionScrpt, AdvancedDataGrid, ArrayCollection, Flex, HierarchicalData
Esse é o primeiro post de uma série que pretendo escrever sobre o AdvancedDataGrid, quem não ficou empolgado quando viu pela primeira vez algo sobre o ADG? E quem não ficou decepcionado quando tentou usar pela primeira vez o ADG? Se você respondeu sim para as duas perguntas saiba que você não está sozinho, a primeira vista ele parece o componente dos sonhos mas na hora de usar ele rapidamente vira o componente dos pesadelos.
Bem vamos ao que interessa, esse primeiro post vai ser só uma dica muito simples mas que faz toda a diferença, quando a origem dos dados é um arrayCollection vindo de um RemoteObject para poder usar o hierarchicalData todos os objetos que são filhos de outro objeto tem que se chamar “children” ou ter o mesmo nome que tem que ser indicado na propriedade childrenField.
No próximo post da série irei mostrar como dar refresh em uma hierarchicalData.
Deixe um comentário
9 Junho, 2008 às 11:52 pm (Componentes, Flex)
Tags: ActionScrpt, Componentes, datas, Flex, validador
Recentemente estava precisando validar se uma data é maior que a outra, então criei esta classezinha simples que estende a Validators, ela recebe duas datas e compara e primeira com a segunda, se a segunda não for maior que a primeira ela coloca a mensagem de erro na segunda, segue o código.
Leia o resto deste post »
Deixe um comentário
28 Maio, 2008 às 4:46 am (Flex, upload)
Tags: Flex, ScreenCast, segurança, upload
Esse post é um extensão do screenCast que o Fábio Vedovelli postou sobre upload de arquivos com o flex.
O post original pode ser visto aqui.
Esse screenCast do Fábio foi o ponto de partida para uma discussão sobre segurança no upload de arquivos com o flex na lista flex-brasil.
Se quiser vá direto ao screenCast:
Extensão do post do Ved sobre upload – segurança
Não entrarei na parte server-side do aspecto de segurança, mesmo porque esse script pode ser usado com uma infinidade de liguagens server-side e cada uma delas tem seu modo de lidar com essa questão, mas não vá achando que não é necessário uma verificação server-side, muito pelo contrário, em se tratando de upload de arquivos É EXTREMAMENTE, IMPRETERIVELMENTE, OBRIGATORIAMENTE NECESSÁRIO IMPLEMENTAR UMA POLITICA DE SEGURANÇA SERVER-SIDE.
Leia o resto deste post »
2 Comentários
28 Maio, 2008 às 1:17 am (Flex, library)
Tags: biblioteca, Flex, iconfile, ScreenCast
Nesse terceiro post da série sobre flex library eu irei falar sobre como usar o metatag [IconFile] para alterar o ícone que aparece ao lado dos componentes na aba components do modo design.
Se você não sabe o que é, pra que serve ou como criar uma biblioteca flex de uma lida nos primeiros posts dessa série:
Biblioteca flex parte 1 – Criando uma biblioteca
Como de custume, se você preferir vá direto para o screenCast deste post:
Biblioteca flex parte 5 – usando o [IconFile] metatag
A princípio pode parecer perda de tempo criar ícones para seus componentes, mas quando sua biblioteca começar a ficar grande você vai ver que facilita bastante na hora de achar o componente desejado na lista de custom da aba de components do modo design do flex builder.
Leia o resto deste post »
2 Comentários