[RESOLVIDO] Dúvida com ordenação datagrid Flex

9 respostas
G

Estou com um problema em minha aplicação Flex.

Tenho um DataGrid com uma coluna renderizada com componente checkbox (inline) e outras três colunas que mostram valores do tipo inteiro, string e string respectivamente. As três colunas utilizam o labelfunction para encontrar os valores a serem exibidos, isso porque, a collection do meu dataProvider é um tipo de objeto que possui um atributo cujo tipo é outro objeto, e são os atributos desse objeto-filho que são exibidos com esse labelfunction.

O problema, é que quando eu clico em uma das colunas da minha grid, cuja identificação é descrição e possui um sortcomparefunction definido, a seleção do checkbox se perde, ou seja, parece que a ordenação faz a grid se perder quanto aos checkboxes. Ao clicar em uma das outras duas colunas id (int - convertido em string) e código (string), que utilizam a mesma função sortcomparefunction, a seleção dos checks funciona corretamente, porém a ordenação da coluna descrição para de funcionar.

Não consigo chegar a um consenso. Já tentei mudar a renderização, tentei atualizar diretamente na lista, criar um novo sort, mas nada funciona, aparentemente por ser um objeto interno.

Alguém tem alguma luz ou já passou por situação semelhante?

Obrigada

9 Respostas

V

tem como colocar o codigo fonte?

G

Oi, segue o código fonte:

<!-- Código do DataGrid -->
<mx:DataGrid headerRelease="headerReleaseFunc(event)" width="100%" height="100%" horizontalScrollPolicy="on" id="dtgPesquisa"  dataProvider="{ar}">
   	   	<mx:columns>
	   	   	<mx:DataGridColumn editable="true"  sortable="false" rendererIsEditor="true" dataField="check" textAlign="center" width="10" editorDataField="selected">
				<mx:itemRenderer>
					<mx:Component>
						<mx:CheckBox click="listarCheck(event)" >
							<mx:Script>
								<![CDATA[
									private function listarCheck(event:Event):void{
						        			data.check = !data.check;
						        		}
								]]>									
							</mx:Script>
					        </mx:CheckBox>
					</mx:Component>
				</mx:itemRenderer>
			</mx:DataGridColumn>
                <mx:DataGridColumn headerText="codigo" dataField="codigo" labelFunction="getProperty" sortCompareFunction="compareString"/>
   	        <mx:DataGridColumn headerText="id" dataField="id" labelFunction="getProperty" sortCompareFunction="compareString"/>
   	   <mx:DataGridColumn headerText="descricao" dataField="descricao" labelFunction="getProperty" sortCompareFunction="compareString"/>
</mx:DataGrid>

<!-- Código do labelfunction == getProperty-->
private function getProperty(item:Object, col:DataGridColumn):String{
	var c:Object = ObjectPai(item).colObjetoFilho.getItemAt(0);
		    	
	switch (col.dataField) {
		case "id": return String(c.id); break;
	        case "descricao": return c.descricao; break;
	    	case "codigo": return c.codigo; break;
	 }
	return "";
}

<!-- Código do sortCompareFunction = compareString -->
private function compareString(itemA:Object, itemB:Object):int {
	 return ObjectUtil.stringCompare( 
	        		ObjetoPai(itemA).colObjetoFilho.getItemAt(0)[currentDataField],
	        		ObjetoPai(itemB).colObjetoFilho.getItemAt(0)[currentDataField], 
	        		true
	  );
}

<!--Código do headerRelease - obter currentDataField-->
private function headerReleaseFunc(event:DataGridEvent):void{
	if(event.columnIndex==0){
		event.preventDefault();
       		event.stopPropagation();
	} else { 	
		currentDataField = event.dataField;
	}
}

Alguma ajuda?

F

Greice,
Sempre q utilizar um itemrenderer sobreescreva o método set data é este método q irá prover a “linha” q o renderer irá mostrar e outra coisa importante, o Flex por perfomance não gera um renderer para cada linha do arraycollection ele reaproveita os objetos criados para mostrar as linhas visiveis, isto é, digamos q o teu grid mostre 10 linhas por vez, o Flex irá criar 10 renderers, qd vc der scroll para mostrar a linha 11 o Flex irá pegar o renderer da linha 1 q não estará mais visível e irá mostrá-lo na linha 11 mas antes irá executar o método set data.

[]s
Espero ter ajudado.

G

Oi Fabio,

Obrigada por responder. Então, eu tentei sobrescrever o método set data, tanto dentro do component (junto com a função listcheck), quanto fora acessando por outerDocument, mas ainda assim o problema persistiu.
O estranho é que a mesma ordenação deu certo para as outras duas colunas… estou desconfiando que o stringCompare tem problemas para ordenar uma string de um objeto interno, porque o campo código em questão, apesar de ser string é composto por números, e a seleção funciona perfeitamente.

F

Greice,
Vc terá um set data parecido com esse:

override public function set data(value:Object):void
        {
             super.data = value;
             selected = !data.check;
        }

Acho q vc tem q ter o código acima e o teu listarCheck e acredito q vc deve remover o editorDataField, pq este último informa qual o campo do renderer q irá alimentar o dataField e o teu listarCheck já está fazendo isso.

[]s

G

Fabio,

Fiz da forma como você colocou, sobrescrevendo o set data e tirando o editordatafield, mas os erros ainda persistem: Quando ordeno pela coluna descrição o checkbox não pega a seleção; quando ordeno pela coluna código ou id o checkbox funciona, mas a ordenação da descrição falha… está dificil achar uma solução…

G

Fabio e demais que tiverem o mesmo problema…

Consegui resolver meu problema de ordenação graças ao plugin de debug… :lol:

Há um bug no flex. Como eu acesso um atributo do objeto filho do objeto principal do dataprovider, ele não reconhece o campo em questão.

Ou seja, na linha: <mx:DataGridColumn headerText="descricao" dataField="descricao" labelFunction="getProperty" sortCompareFunction="compareString"/>

O campo descricao ele reconhece como sendo do objeto que compõem a collection ar (dataProvider), e como meu ObjetoPai não possui esse atributo, ele não ordena e ‘zoa’ meu checkbox. O que fiz foi criar esse atributo no ObjetoPai, e o problema foi resolvido.

Fabio, sua ajuda foi de grande valia também, pois sem sobrescrever o data, a seleção não funciona também.

Obrigada pela ajuda.

Greice

F

Greice,
Que bom, blz.
Se não me engano no SDK 3.5 é possível colocar no dataField algo como objeto.propriedade.
Não tinha percebido no seu código mas ou se usa labelFunction ou dataField.

[]s
Qq coisa estamos aí.

G

Achei que havia resolvido meu problema, mas acabei achando outro…

Eu percebi que, mesmo ordenando ou não a grid, quando eu clico em um checkbox, ele seleciona e executa a ação que eu quero com a seleção correta. No entanto, quando eu seleciono outro checkbox e tiro a seleção do anterior, a ação é executada usando o item anterior e não o que esta selecionado no checkbox. O que percebi é que, independente do check, quem está selecionando ou não meus intens é o click na linha da tabela. Tem como desabilitar esse click para ele entender que é só o checkbox selecionado?

Descobri o erro, estava na verificação do campo selecionado.

Criado 6 de dezembro de 2010
Ultima resposta 7 de dez. de 2010
Respostas 9
Participantes 3