JSF: chamada duplicada

7 respostas
F

Tenho uma tela que exibe um dataTable com dados vindos do banco.
Estou tentando implementar uma paginação manual, onde eu passo para uma procedure os registros que eu quero, como por exemplo do 20 ao 30, justamente pela lentidão da mesma.

<f:view>
	    <a4j:loadStyle src="/css/main.css" />
	    <a4j:loadStyle src="/css/tabulacao.css" />
	    <a4j:keepAlive beanName="funcionario" />
	    <rich:spacer height="20" />
	    <h:form id="formList">
		<a4j:outputPanel layout="block"
						 styleClass="linkAreaLeft"
						 rendered="true"
						 style="line-height: 35px; height: 35px;">
			<t:div style="float: right;">
				<h:outputLabel style="display: inline;" value="Status: " for="status"/>
				<h:selectOneMenu value="#{funcionario.flAtivo}" style="margin-right: 13px;">
					<f:selectItem itemLabel="Ativo" itemValue="S" />
					<f:selectItem itemLabel="Inativo" itemValue="N" />
					<a4j:support status="statusWait" action="#{funcionario.buscaPorCampo}" event="onchange" reRender="tblListTodos">
						<t:updateActionListener value="#{funcionario.flAtivo}" property="#{funcionario.funcionario.flAtivo}"></t:updateActionListener>
					</a4j:support>
				</h:selectOneMenu>
			</t:div>
			<h:outputText value="Lista de Funcionários" styleClass="linkText"/>
			<h:outputLink value="cadastro.jsf">
				<h:graphicImage value="/imgs/ico_inserir.gif" />
				<h:outputText value="Inserir" styleClass="linkText" />
			</h:outputLink>
		</a4j:outputPanel>
		<rich:spacer height="10"/>
		<h:messages styleClass="alerta mensagem"></h:messages>

			<h:inputHidden id="idFunc" value="#{funcionario.idFuncionario}" />
			<rich:dataTable id="tblListTodos"
			                value="#{funcionario.listaTodos}"
			                var="func"
			                lang="pt_BR"
			                rowKeyVar="rowIndex"
			                width="750px"
			                captionClass="tblCaption"
			                align="center"
			                rows="20"
			                rowClasses="noClass,rowClass"
			                reRender="ds">
				
				<rich:column styleClass="leftAlign"
				             width="320px"
				             label="Nome">
					<f:facet name="header">
						<h:outputLabel value="" style="width: auto;">
				    		<h:inputText id="funcNome" style="font-size: 10px;" size="40" label="Nome" value="#{funcionario.funcionario.dsNome}" />
				    		<br />
				    		<h:outputText value="Nome"/>
				    	</h:outputLabel>
					</f:facet>
					<h:outputText value="#{func.dsNome}"/>
				</rich:column>
				
				<rich:column styleClass="leftAlign"
				             width="80px">
					<f:facet name="header">
						<h:outputLabel value="" style="width: auto;">
				    		<h:inputText id="funcMatricula" style="font-size: 10px;" maxlength="6" size="10" label="Matricula" value="#{funcionario.funcionario.nrMatriculaS}" />
				    		<br />
				    		<h:outputText value="Matricula"/>
				    	</h:outputLabel>
					</f:facet>
					<h:outputText value="#{func.nrMatricula}"/>
				</rich:column>
				
				<rich:column styleClass="leftAlign"
				             width="370">
				    <f:facet name="header">
						<h:outputLabel value="" style="width: auto;">
				    		<h:inputText id="funcCargo" style="font-size: 10px;" size="30" label="Cargo" value="#{funcionario.funcionario.cargo.dsDescricao}" />
				    		<br />
				    		<h:outputText value="Cargo"/>
				    	</h:outputLabel>
					</f:facet>
					<h:outputText value="#{func.cargo.dsDescricao}"/>
				</rich:column>
				
				<rich:column styleClass="centerAlign"
				             width="90px"
				             label="Ações">
					<f:facet name="header">
						<h:outputLabel value="">
							<h:commandLink action="#{funcionario.buscaPorCampo}">
								<h:graphicImage alt="Filtrar" url="/imgs/ico_buscar.gif" />
				    		</h:commandLink>
							<br />
				    		<h:outputText value="Ações" />
				    	</h:outputLabel>
					</f:facet>
					<rich:spacer width="5" rendered="true"/>
					<h:commandLink action="#{funcionario.inativar}"
								   onclick="inativar(#{func.idFuncionario})"
								   rendered="#{func.flAtivo ne 'N'}">
						<h:graphicImage value="/imgs/ico_excluir.gif"  title="Inativar"/>
					</h:commandLink>
					<h:commandLink action="#{funcionario.reativar}"
								   onclick="reativar(#{func.idFuncionario})"
								   rendered="#{func.flAtivo eq 'N'}">
						<h:graphicImage value="/imgs/ico_reativar.gif"  title="Reativar"/>
					</h:commandLink>
					<rich:spacer width="5" rendered="true" />
					<h:commandLink action="#{funcionario.editar}"
								   onclick="editar(#{func.idFuncionario})"
								   rendered="true">
						<h:graphicImage value="/imgs/ico_editar.gif" title="Editar"/>
					</h:commandLink>
				</rich:column>
				<f:facet name="footer">
					<h:commandLink action="#{funcionario.fazPaginacao}">
						<h:outputText value="Próximo" />
					</h:commandLink>
				</f:facet>
			</rich:dataTable>
		</h:form>	
		<a4j:status id="statusWait"
		            onstart="#{rich:component('wait')}.show()"
		            onstop="#{rich:component('wait')}.hide()"/>
	    <rich:modalPanel id="wait"
	                     autosized="true"
	                     width="80"
	                     height="50"
	                     moveable="false"
	                     resizeable="false"
	                     styleClass="centerAlign">
			<h:graphicImage value="/imgs/carregando.gif"/>
			<br/><br/>
        	<h:outputText value="Aguarde..." style="font-weight: bold"/>
	    </rich:modalPanel>
	</f:view>

Quando eu clico no 'Próximo' é chamado o método getListaTodos 2x! Vocês fazem idéia do que pode ser isso?
Eu estou boiando! :?

7 Respostas

W

Por um acaso : listaTodos , é um atributo da classe, que tem métodos set e get e dentro do get você carrega a lista?

Até onde eu sei, não tem como “burlar” este duplo acesso que o framework faz, quando encontra o padrão “get”.

Mas dá pra criar um método normal tipo : listaTodos e acessar ele via action na página.

F

Vlw weberdls! Implementei um método carregando a lista e minimizou o problema!
Agora esse lance de acessar 2x o atributo é novidade para mim! Você saberia explicar com mais detalhes?

Obrigado!

rponte

FerTriPa:
Vlw weberdls! Implementei um método carregando a lista e minimizou o problema!
Agora esse lance de acessar 2x o atributo é novidade para mim! Você saberia explicar com mais detalhes?

Obrigado!

Os métodos getters podem ser invocados diversas vezes durante o ciclo de vida do Faces. E isso torna-se ainda pior quando se está trabalhando com componentes de iteração, como h:dataTable, ui:repeat etc.

A dica é: evite deixar regras/lógicas caras (pesadas) dentro de métodos getters, caso contrário você terá problemas de performance para processar e exibir as páginas!

W

rponte:
FerTriPa:
Vlw weberdls! Implementei um método carregando a lista e minimizou o problema!
Agora esse lance de acessar 2x o atributo é novidade para mim! Você saberia explicar com mais detalhes?

Obrigado!

Os métodos getters podem ser invocados diversas vezes durante o ciclo de vida do Faces. E isso torna-se ainda pior quando se está trabalhando com componentes de iteração, como h:dataTable, ui:repeat etc.

A dica é: evite deixar regras/lógicas caras (pesadas) dentro de métodos getters, caso contrário você terá problemas de performance para processar e exibir as páginas!

E qual o motivo desta duplicação de chamadas, tem um porque ou é bug? JSF2.0 corrigiu isso?

rponte

Não, não é bug!

A própria especificação comenta sobre isso! O framework precisa obter os dados do managed bean através de EL (Expression Language), e sempre que isso se faz necessário a EL é avaliada dentro do ciclo de vida.

Provavelmente em algumas fases do ciclo o Faces avalia a EL uma única vez e trabalha em cima desse valor, mas no final acredito que isso dependa de implementação para implementação.

No mais, o aconselho é evitar processamentos pesados dentro do getter, caso contrário isso pode se tornar um mau hábito (mais precisamente o slide 60).

W

OK, entendi.

Eu procurei informações sobre isto em todos os lugares, menos na especificação ¬¬

Valeu rponte!

F

Obrigado pela explicação! Entendi (:
PS: eu peguei esse método já desenvolvido… nunca curti implementar nada dentro de get/set, mas sem muita base teórica!

Criado 18 de maio de 2010
Ultima resposta 21 de mai. de 2010
Respostas 7
Participantes 3