[?] JSF 2 - Problema com backing bean @ViewScoped + Ajax

1 resposta
blacksheep

Olá pessoal!
Comecei a brincar com JSF 2 há alguns dias e até aqui tem sido muito divertido. Estou desenvolvendo uma pequena aplicação de gerenciamento de bookmarks com a ajuda da biblioteca de componentes PrimeFaces (que btw, dá um pau no RichFaces rs).
Único problema que encontrei até agora é esse: tenho uma página onde são exibidos todos os bookmarks pertencentes ao grupo que o usuário selecionou na página anterior e pra cada bookmark nessa página disponibilizei (utilizando o h:commandLink) as opções “Editar” e “Deletar”. O código da página segue abaixo (“Deletar” na linha 45):

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.prime.com.tr/ui">
    <h:head>
        <title><h:outputFormat value="#{msg.tituloPgVisualizarGrupo}"><f:param value="#{managedCategoria.categoria.nomeCategoria}" /></h:outputFormat></title>
    </h:head>
    <h:body>

        <f:metadata>
            <f:viewParam id="idCategoria" name="id" value="#{managedCategoria.categoria.codigoCategoria}"
                         required="true"
                         requiredMessage="#{msg.especifiqueUmId}"
                         converterMessage="#{msg.especifiqueUmIdValido}"
                         validatorMessage="#{msg.especifiqueIdPositivo}">
                <f:validateLongRange minimum="1"/>
            </f:viewParam>
            <f:event type="preRenderView" listener="#{managedCategoria.actionVisualizarCategoria}" />
        </f:metadata>


        <h:form id="formVisualizarCategoria" prependId="false">

            <p:panel id="panelVisualizarCategoria" header="#{managedCategoria.categoria.nomeCategoria}">

                <h:panelGrid columns="1">

                    <h:link outcome="/bookmark/criar" value="#{msg.adicionarBookmark}"><f:param name="idCategoria" value="#{managedCategoria.categoria.codigoCategoria}" /></h:link>

                    <p:messages globalOnly="true" />

                    <h:outputText value="#{msg.nenhumBookmarkCadastrado}" rendered="#{empty managedCategoria.categoria.bookmarkList}" />

                    <h:dataTable id="listaBookmarksCategoria" var="bookmark" value="#{managedCategoria.categoria.bookmarkList}" rendered="#{not empty managedCategoria.categoria.bookmarkList}">

                        <h:column>
                            <h:outputText value="#{bookmark.tituloBookmark}: " /><h:outputLink value="#{bookmark.urlBookmark}" target="_blank">#{bookmark.urlBookmark}</h:outputLink>
                        </h:column>

                        <h:column>
                            (<h:link outcome="/bookmark/editar" value="#{msg.editar}"><f:param name="idBookmark" value="#{bookmark.codigoBookmark}" /></h:link>
                            |
                            <h:commandLink value="#{msg.deletar}" actionListener="#{managedCategoria.actionExcluirBookmark(bookmark)}"
                                           onclick="if (!confirm('#{msg.confirmarExcluirBookmark}')) return false;">
                                <f:ajax render="@form" />
                            </h:commandLink>)
                        </h:column>

                    </h:dataTable>

                </h:panelGrid>

            </p:panel>

        </h:form>

    </h:body>
</html>

Então quando clico no link, é exibido um confirm do JavaScript e caso o retorno seja positivo a action do meu backing bean é chamada. Segue o código do meu backing bean:

package managed;

import entities.Bookmark;
import entities.Categoria;
import entities.Usuario;
import java.util.Date;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ComponentSystemEvent;
import session.CategoriaFacade;

/**
 *
 * @author Jon Welzel
 */
@ManagedBean
@ViewScoped
public class ManagedCategoria extends ManagedHelper {
    private Categoria categoria;

    @EJB private CategoriaFacade categoriaFacade;

    @ManagedProperty(value="#{managedUsuario}") private ManagedUsuario managedUsuario;

    /** Creates a new instance of ManagedCategoria */
    public ManagedCategoria() {
        categoria = new Categoria();
    }

    public Categoria getCategoria() {
        return categoria;
    }

    public void setCategoria(Categoria categoria) {
        this.categoria = categoria;
    }

    public ManagedUsuario getManagedUsuario() {
        return managedUsuario;
    }

    public void setManagedUsuario(ManagedUsuario managedUsuario) {
        this.managedUsuario = managedUsuario;
    }

    public String actionCadastrarCategoria() {
        Usuario usuario = managedUsuario.getUsuario();
        categoria.setUsuario(usuario);
        categoria.setDataCriacaoCategoria(new Date());
        categoriaFacade.create(categoria);
        usuario.getCategoriaList().add(categoria);

        return "/usuario/homeUsuario?faces-redirect=true";
    }

    public void actionVisualizarCategoria(ComponentSystemEvent evt) {
        categoria = categoriaFacade.find(categoria.getCodigoCategoria());
    }

    public void actionExcluirBookmark(final Bookmark bookmark) {
        System.out.println("actionExcluirBookmark: " + bookmark);
        mostrarMensagemInfo("bookmarkExcluidoSucesso"); //Exibe um FacesMessage na página

//        return "/categoria/visualizar?id=" + categoria.getCodigoCategoria() + "&faces-redirect=true";
    }
}

O problema é que quando carrego a página e clico na opção “Deletar” pela primeira vez tudo funciona certinho, a action é invocada, o console do servidor exibe a mensagem “INFO: actionExcluirBookmark: entities.Bookmark[codigoBookmark=1]” e o FacesMessage é exibido. Mas quando clico pela segunda vez nada acontece, o FacesMessage some da tela e a action do meu backing bean não é chamada. Gostaria de saber o porque desse comportamento e se tem como resolver esse problema. Sim, já tentei fazer a mesma coisa mas sem utilizar Ajax. Nesse caso funciona na segunda vez normalmente e nas outras tmb, mas a FacesMessage não é exibida em momento algum (sem contar que tem o reload desnecessário da página). Qualquer ajuda será bem apreciada. Obrigado.

1 Resposta

blacksheep

bump

Criado 7 de agosto de 2010
Ultima resposta 10 de ago. de 2010
Respostas 1
Participantes 1