Antes de tudo, quero dar as boas vindas a você que está visitando este blog, nós da Bindable que queremos compartilhar um pouco de nossos desafios, fique a vontate.
Neste post vou falar sobre um problema que assombra muitos programadores de flex, e compartilhar uma solução que encontrei.
Vamos ao problema: quando se usa um itemRenderer em um AdvancedDataGrid ou um DataGrid com uma coluna que tem que imagens, no evento do scrollbar as imagens se misturam não sendo condizente com o dataProvider. O primeiro passo para resolver o problema é saber reproduzir o mesmo, e é isso que vamos fazer nessa etapa:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="200" layout="absolute" creationComplete="init()"> <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; [Bindable] private var colletionData:ArrayCollection = new ArrayCollection(); /** * Evento é executado quando a Applicação está completa * Inicializa a coleção de dados * */ private function init():void { colletionData =new ArrayCollection([{titulo:'imagem1', descricao:'conteudo com a imamge 1'}, {titulo:'imagem1', descricao:'conteudo com a imamge 1'}, {titulo:'imagem1', descricao:'conteudo com a imamge 1'}, {titulo:'imagem2', descricao:'conteudo com a imamge 2'}, {titulo:'imagem1', descricao:'conteudo com a imamge 1'}, {titulo:'imagem2', descricao:'conteudo com a imamge 2'}, {titulo:'imagem3', descricao:'conteudo com a imamge 3'}, {titulo:'imagem3', descricao:'conteudo com a imamge 3'}, {titulo:'imagem2', descricao:'conteudo com a imamge 2'}, {titulo:'imagem1', descricao:'conteudo com a imamge 1'}, {titulo:'imagem1', descricao:'conteudo com a imamge 1'}, {titulo:'imagem3', descricao:'conteudo com a imamge 3'}, {titulo:'imagem2', descricao:'conteudo com a imamge 3'}, {titulo:'imagem1', descricao:'conteudo com a imamge 1'}, {titulo:'imagem3', descricao:'conteudo com a imamge 3'}, {titulo:'imagem3', descricao:'conteudo com a imamge 3'}, {titulo:'imagem3', descricao:'conteudo com a imamge 3'}, {titulo:'imagem2', descricao:'conteudo com a imamge 2'}, {titulo:'imagem1', descricao:'conteudo com a imamge 1'}, {titulo:'imagem3', descricao:'conteudo com a imamge 3'}, {titulo:'imagem1', descricao:'conteudo com a imamge 1'}, {titulo:'imagem3', descricao:'conteudo com a imamge 3'}] ); gridDados.dataProvider = colletionData; } ]]> </mx:Script> <mx:DataGrid id="gridDados" dataProvider="{colletionData}" width="400" height="200" x="0" y="0"> <mx:columns> <mx:DataGridColumn headerText="Titulo Imagem" dataField="titulo" width="120"/> <mx:DataGridColumn headerText="Descrição" dataField="descricao" width="120"/> <mx:DataGridColumn headerText="Imagem" width="80"> <mx:itemRenderer> <mx:Component> <mx:Box verticalAlign="middle" horizontalAlign="center"> <mx:Script> <![CDATA[ /** * Embeda as 3 imagens que serão utilizada no exemplo * */ [Embed('imagem1.png')] private var Img1:Class; [Embed('imagem2.png')] private var Img2:Class; [Embed('imagem3.png')] private var Img3:Class; /** * Seta no creationComplete a imagem referênte ao data * que veio do dataProvider * * Esse evento só ocorre uma vêz na criação do objeto * */ public function init():void { if(data != null) { if(data.titulo == "imagem1") { img.source = Img1; img.toolTip = data.titulo; } else if(data.titulo == "imagem2") { img.source = Img2; img.toolTip = data.titulo; } else if(data.titulo == "imagem3") { img.source = Img3; img.toolTip = data.titulo; } } else { img.visible=false; } } ]]> </mx:Script> <mx:Image id="img" width="20" height="20" autoLoad="true" creationComplete="init()" /> </mx:Box> </mx:Component> </mx:itemRenderer> </mx:DataGridColumn> </mx:columns> </mx:DataGrid> </mx:Application> |
Como você pode ver, eu crie um itemRenderer que o data define qual imagem será exibida, o resultado disso é:
Veja que os três primeiros itens são da “imagem 1″, como um passe de mágica se você mexer no scrollbar, irá notar que as imagens mudaram, mas perceba que o data continua o mesmo, veja a coluna “Titulo Imagem”.
Agora que já sabemos como reproduzir o problema, vamos a solução que encontrei:
Para resolver esse problema, foi necessário fazer um bindable inline na tag imagem como mostra o itemRenderer a baixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<mx:itemRenderer> <mx:Component> <mx:Box verticalAlign="middle" horizontalAlign="center"> <mx:Script> <![CDATA[ /** * Embeda as 3 imagens que serão utilizada no exemplo * */ [Embed('imagem1.png')] private var Img1:Class; [Embed('imagem2.png')] private var Img2:Class; [Embed('imagem3.png')] private var Img3:Class; ]]> </mx:Script> <mx:Image id="img" width="20" height="20" source="{data.titulo == 'imagem1'?Img1:data.titulo == 'imagem2'?Img2:data.titulo == 'imagem3'?Img3:''}" toolTip="{data.titulo}" autoLoad="true" /> </mx:Box> </mx:Component> </mx:itemRenderer> |
O arquivo final foi:
Se você mexer no scrollBar agora, verá que o problema não mais acontece.
Espero ter contribuído.
Autor:Claudio Araujo




