JSF - 2 views 1 MB [RESOLVIDO -3PAG]

40 respostas
d34d_d3v1l

Galera…

Eu tenho 2 views e 1 MB…
Eu pesquisei aqui no forum e um rapaz (que inclusive criou um framework)
sugeriu mudar o scope do bean para algo do myfaces @AccessViewScoped

Mas eu nao quero ficar adiacionando mta dependencias no meu projeto…
E tb nao quero usar o framework do rapaz.

Então o problema e´que todo crud tem 2 views:
list
form

onde no list eu tenho um form de filtros… uma datatable … e um confirmDelete …
o outro arquivo eu tenho um for aara visualizar/editar os dados …

Eu achava que o viewScoped iria perceber que o managedBean tbem é referenciado na proxima view
e que ele iria manter. Mas não! (PS: outro problema é que estou usando Spring…)

Então, como eu vou manter o MB vivo quando eu trocar de pagina?
Ou como faço um bypass disso para nao precisar mantê-lo vivo?

Só para contextualizar melhor: a tabela tem uma coluna com botao de deletar e editar…
veja:

<p:commandButton id="edit" icon="ui-icon-pencil" action="#{cc.attrs.controller.getFormPath}" ajax="false">
								<f:setPropertyActionListener value="#{entity}" target="#{cc.attrs.controller.entity}" />
							</p:commandButton>

Eu tenho um action que o metodo retorna algo do tipo: /view/grupo/formGrupo.xhtml
e usando o setPropertyActionListener eu sei que o meu atributo “Grupo entity” que esta
na outra view será carregado nos campos e ao salvar, vou editá-lo [método saveOrUpdate]!

Este é um dos problemas… O outro problema vou postar em outro tópico :slight_smile:
Mas envolve FlashScope.

40 Respostas

lele_vader

Um problema.

Spring não tem view scope que eu saiba.
Por isso que os seus beans não devem manter os valores.
Eu uso com um servidor jee e funciona corretamente.

d34d_d3v1l

lele_vader:
Um problema.

Spring não tem view scope que eu saiba.
Por isso que os seus beans não devem manter os valores.
Eu uso com um servidor jee e funciona corretamente.

O ViewScoped se manter por duas paginas??
com ViewScpoed??

*EDIT:
Mas eu to usando Spring para CDI,
Spring Data, e para controle transacional…
q nem vi q vc disse num post uma vez.

Tem como eu deixar o JSF tomar conta do Escopo
e deixar o spring quetin só praquilo ali?

lele_vader

Duas páginas não.
O view scope tem que se manter na mesma página.
Se precisa disso daí usa session scope talvez.

lele_vader

Mas não sei como o spring vai fazer cdi de um managed bean com escopo de view não.

d34d_d3v1l

cara, mas imagine um sistema com 300 tabelas (praticamente 200~250 cruds)
Agora imagine 1k usuarios acessando simultaneamente…

Não dá né??
A não ser que tenha um workaround ou algo assim pra eu remover da sessão manualmente depois!

lele_vader

Não disse para colocar todas os managed beans como sessão.
Ainda não entendi para que você quer essa questão dos managed beans ?

lele_vader

Por exemplo no editar lá e deletar.
Você poderia passar o id ou o próprio objeto para a próxima página e o managed bean iria recuperar o objeto setado e faria normalmente.

d34d_d3v1l

lele_vader:
Não disse para colocar todas os managed beans como sessão.
Ainda não entendi para que você quer essa questão dos managed beans ?

Então cara, é porque todo crud tem duas paginas:
listEntidade.xhtml
fromEntidade.xhtml

Onde todo LIST tem um componente que criei que representa os filtros … Um componente que contem o datatable e outro componente que contém um dialogo para deletar a entidade.

Todo FORM tem um formulário para a pessoa visualizar/editar

Na datatable eu tenho:

<p:commandButton id="edit" icon="ui-icon-pencil" action="#{cc.attrs.controller.getFormPath}" ajax="false">
								<f:setPropertyActionListener value="#{entity}" target="#{cc.attrs.controller.entity}" />
							</p:commandButton>

onde o getFormPath vai retornar /view/entidade/formEntidade.xhtml
eu seto o valor na entidade que tenho no MB tipo “Entidade entity”
e depois quando ele muda de pagina, ela já aparece com os campos carregados.

Pronto! :slight_smile:
É por isso que eu preciso manter o MB vivo por duas views

lele_vader

Você não precisa manter todo o managed Bean vivo.
Você precisa manter a entidade viva.

Passa por parâmetro para a próxima url.

lele_vader

Ou nesse seu propertyActionListener, poderia colocar uma propriedade para visualizar ou alterar.

E na outra página pegar o valor dessa propriedade.

lele_vader

Agora você manda redirect entre uma tela e outra ?

d34d_d3v1l

lele_vader:
Você não precisa manter todo o managed Bean vivo.
Você precisa manter a entidade viva.

Passa por parâmetro para a próxima url.

tem algum pedacin de código rapidinho de como eu faria isso?
f:param né ?

ai do outro lado como que eu pego ele? como?

ahh aproveitando… isso vai funcionar na caixa de dialogo que tenho para deletar?
ou tbem tenho que fazer do mesmo jeito?

PS: esqueço o setProperty… née?

lele_vader

Acho que tem que ser f:attribute, pois você vai querer passar os objetos.
Lembrando que se for jsf 2 você pode passar parâmetros para os métodos de um managedBean.

Se usar f:param no seu managed bean terá que pegar por se não me engano:

Entidade entidade = (Entidade) request.getFacesContext().getRequestParamMap().getAttribute(“nomeAtributo”);

Daí acho que poderia fazer assim (se for usar o parâmetro no método do managed bean):

public String prepararEditar(Entity objeto){
   setEntidade(objeto);

}
return "string para proxima pagina";

e na outra página você pode usar
#{bean.entidade.campoX}

lele_vader

Como você cria essa caixa de diálogo ?
Pode-se fazer do mesmo jeito.

d34d_d3v1l

uééé mas isso não tem diferença do que eu ja estava tentando fazer !
PS: ja que o spring n tem viewscope… eu vi um workaround
http://www.harezmi.com.tr/spring-view-scope-for-jsf-2-users/
qq vc acha?

lele_vader

E porque parou de fazer dessa forma ?

d34d_d3v1l

O que acontece é o seguinte
eu tinha o MB com @ViewScoped e @Component anotado…
ai tava usando tranquilo ACHANDO que o viewScoped tava funcionando…

depois fui ver que nao funciona! Descobri isso hoje!
Aí to me virando aqui pra ver oq ue faço para ele matar o MB depois que sair dessas duas views!

lele_vader

Se você colocar como request ele só vai funcionar a cada requisição.

O view scope também não é muito recomendado eu acho para o seu modelo que tem várias páginas.

Mesmo se não fosse spring não funcionaria eu acho.

lele_vader

Nos links você prepara os objetos que a próxima página irá ver.

Lembrando que jsf não é struts 1 com 1 página por action (no caso managed bean).

Você pode colocar 1 managed beans para todas as páginas correlacionadas.

d34d_d3v1l

então cara, eu coloquei como request scope…
e adivinha???

A paginação do datatable não funciona.
Então, tem que ser NO MINIMO viewScope

como que faço se eu tenho um MB assim:

@Component
@ViewScope
public class GrupoController extends BaseController<Grupo, Integer> {

tem alguma coisa que eu posso fazer aí pro viewScope funcionar?

as minhas dependencias estão injetadas assim:

@PersistenceContext
	private EntityManager entityManager;

	@Autowired
	private GrupoService grupoService;

	@Autowired
	private MessageUtil messageUtil;

	@Autowired
	private GenericFilterService genericFilterService;
lele_vader

Como é esse datatable ?
Qual o erro que ocorre no datatable ?

Poderia colocar somente um managed bean que cuida dele como session e toda a parte de datatable ir para ele.

d34d_d3v1l

lele_vader:
Como é esse datatable ?
Qual o erro que ocorre no datatable ?

Poderia colocar somente um managed bean que cuida dele como session e toda a parte de datatable ir para ele.

putz, nao tem como fazer o viewScoped funcionar?? :frowning:

Ué, quando clica na proxima pagina nada acontece…
acontece como se estivesse na primeira pagina…

lele_vader

Mesmo se fosse view scope.
Quando trocar de página é outra requisição, mesmo que ambas tenham o mesmo managed bean.

Não sei se vai funcionar para os seus problemas.

Sobre o datatable me mostra como você o fez.

d34d_d3v1l

lele_vader:
Mesmo se fosse view scope.
Quando trocar de página é outra requisição, mesmo que ambas tenham o mesmo managed bean.

Não sei se vai funcionar para os seus problemas.

Sobre o datatable me mostra como você o fez.

cara, se eu conseguir colocar o MB como viewScope, então o datatable e o delete vão funcionar…
Aí quando for pra trocar de página, eu penso em outra solução tipo… passar por parametro pra outra view…
e usar só um metodo o MB pra buscar do banco aquela entidade e dps jogar os dados pra view… Ou então eu coloco tudo na mesma view
e faço umas macumba com RENDERED pra sumir com os formularios de tabela/filtro

entende?

lele_vader

E hoje o view scope não funciona ?
É isso ?
Porque o delete também não funciona por sinal ?

Você para resolver o problema do datatable poderia colocar um managedBean para fazer isso e colocá-lo com um escopo maior talvez.
E usar esse como dependência do seu managedBean da entidade.

d34d_d3v1l

lele_vader:
E hoje o view scope não funciona ?
É isso ?
Porque o delete também não funciona por sinal ?

Você para resolver o problema do datatable poderia colocar um managedBean para fazer isso e colocá-lo com um escopo maior talvez.
E usar esse como dependência do seu managedBean da entidade.

o ViewScope não funciona!
:frowning:

Se eu resolver isso, 70% dos problemas somem…
Pq aí não terei mtas modificaçoes na estrutura basica
dos cruds

lele_vader

Bom. Tenta aquela parada lá do spring então.
Eu talvez colocaria um bean de sessão para cuidar dos datatables.
Daí não perderia-se o valor.
Mas não sei o impacto disso aí no seu sistema.
Realmente com o spring não sei se por vias normais bean scope funciona.
Talvez em uma versão mais nova.

vlw.

d34d_d3v1l

lele_vader:
Bom. Tenta aquela parada lá do spring então.
Eu talvez colocaria um bean de sessão para cuidar dos datatables.
Daí não perderia-se o valor.
Mas não sei o impacto disso aí no seu sistema.
Realmente com o spring não sei se por vias normais bean scope funciona.
Talvez em uma versão mais nova.

vlw.

aquela parada do spring esta cheirando mta gambi… to com medo de fazer, depois me perder nela! :frowning:
pq é um projeto grande nao posso deixar as coisas fugirem do controle!

Como vc anota os seus managedBean se vc ainda usa o Spring para injeção de dependencia?

lele_vader

Não uso spring.rsrs
Em uma aplicação que desenvolvo em casa eu acabei usando servidor de aplicação.

Vê com alguém mais experiente como resolver o seu problema.

d34d_d3v1l

Obrigado pela ajuda!

Abri outro tópico…
vou colocar [sem solucao] neste
kkkkkkkkkkkk

G

amigo,

o seu problema pode ser resolvido simplesmente usando facelets e criando uma tela de crud genérica. no sistema que trabalho é feito dessa forma e funciona direitinho.

d34d_d3v1l

gambazinho:
amigo,

o seu problema pode ser resolvido simplesmente usando facelets e criando uma tela de crud genérica. no sistema que trabalho é feito dessa forma e funciona direitinho.

mas é isso que eu tenho…
só que com duas views pra cada entidade

G

tipo vc tem 20 entidades e apenas 2 views genéricas que atendem a todas elas, é isso?

d34d_d3v1l

duas views vc quer dizer xhtml??
Se vc tiver um ssitema todo com 2 xhtml eu piro!
me fala como vc fez isso kkkkk

eu tenho um template…
um MB abstrato… e componentes.
Atualmente minha view está assim
(LIST):

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:p="http://primefaces.org/ui"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:po="http://java.sun.com/jsf/composite/componente"
	template="/templates/template.xhtml">
	<ui:define name="content">

			<h:form id="filterForm" style="padding-right: 10px;">	
		        <po:filter id="filter" fileName="#{msg['entity.grupo']}" controller="#{grupoController}" />		       				   			
			</h:form>
	        	        
			<!--  o ID do form eh padrao para todos as views -->
			<h:form id="mainForm">
				<po:datatable id="datatable" controller="#{grupoController}">
						<p:column headerText="#{msg['entity.id']}" style="width:80px">
							<h:outputText value="#{entity.id}" />
						</p:column>
		
						<p:column headerText="#{msg['entity.descricao']}" sortBy="#{entity.descricao}">
							<h:outputText value="#{entity.descricao}" />
						</p:column>
		
						<p:column headerText="#{msg['entity.idade']}" sortBy="#{entity.idade}">
							<h:outputText value="#{entity.idade}" />
						</p:column>
		
						<p:column headerText="#{msg['entity.data']}" sortBy="#{entity.data}">
							<h:outputText value="#{entity.data}" />
						</p:column>
		
						<p:column headerText="#{msg['entity.grupo.tipo']}" sortBy="#{entity.tipo}">  
							<h:outputText value="#{entity.tipo}" />
						</p:column>
				</po:datatable>
			</h:form>
			
			<po:confirmDelete deleteAction="#{grupoController.delete}" />	
			

	</ui:define>
</ui:composition>

e tenho o form que é o formulario mesmo com os campos…
o componente de filtro conversa com o componente da tabela que conversa com o comopnente de dialogo…

E a tabela, quando editar ou exclui seta a propriedade para o bean e o action manda pra outra view.

G

então, aqui temos 1 xhtml genérico de CRUD que é utilizado por todas as entidades.
vc não precisa ter dois xhtml, vc pode ter 1 só com LIST e FORM o segredo é vc usar o rendered pra definir quando mostrar qual.
amanhã olho como ta e posto aqui.

d34d_d3v1l

beleza!
valeu

Leonardo_Gaona

Faz tudo em uma única view com AJAX cara, pra que ficar criando 2 views pra um CRUD? Você pode usar um h:panel com todos os campos pra edição/criação de registro, e exibir ou escondê-lo com requisições ajax e alguns flags no seu managed bean para controlar a exibição do painel.

O View Scope é possível com Spring sim, entretanto é necessário implementá-lo. Mas como o lele_vader disse, beans com este escopo “somem” após a mudança da view. Mais um motivo pra você usar AJAX :slight_smile:

d34d_d3v1l

Leonardo Gaona:
Faz tudo em uma única view com AJAX cara, pra que ficar criando 2 views pra um CRUD? Você pode usar um h:panel com todos os campos pra edição/criação de registro, e exibir ou escondê-lo com requisições ajax e alguns flags no seu managed bean para controlar a exibição do painel.

O View Scope é possível com Spring sim, entretanto é necessário implementá-lo. Mas como o lele_vader disse, beans com este escopo “somem” após a mudança da view. Mais um motivo pra você usar AJAX :slight_smile:

Cara, eu tentei usar os workarounds do ViewScoped para Spring.
Primeiro: todas as minhas dependencias precisaram implementar Serializable
Segundo: nem o ajax da paginação do datatable funcionou
Terceiro: eu tenho um esquema de filtro dinamico, onde o cara adiciona e remove os filtros (campos) que ele quer. Tbem não funcionou :frowning: PS: tb com ajax!

A questão de trocar de pagina é mínima para mim… Posso perder a instancia do MB depois nao tem problema…
Então eu to pensando na seguinte solução: por favor veja aqui

abraços!

lindberg713

Cara, nestes links abaixo esta a solução tanto para quem usar SPRING quanto para quem usa CDI.

http://www.guj.com.br/java/257228-resolvido-como-m…n-entre-duas-paginas-com-jsf-2

http://lindbergframework.blogspot.com.br/2012/02/c…-estado-de-um-managedbean.html

Espero que te ajude. Eu mesmo foi quem implementou e a utilizo em varios projetos.

d34d_d3v1l

Galeraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!!

lindbergframework funciona perfeitamente!!

Muito bom! Mantenho o meu MB ‘vivo’ durante toda pagina que possui referencia a ele !
muito bom…

valeuuuuuuuu cara!

Criado 4 de dezembro de 2012
Ultima resposta 6 de dez. de 2012
Respostas 40
Participantes 5