Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

CommandLink para remover livro não atualiza a tela

Nessa versão com CDI o commandLink para remover livros, remove o livro, entretanto não está atualizando a tela. Só atualiza se eu entrar novamente em livro.xhtml.

Preciso de ajudar com isso por favor.

Fragmento de livro.xhtml:

<p:column headerText="Remover">
          <h:commandLink value="remove" action="#{livroBean.remover(livro)}" />
</p:column>    
</p:dataTable>
@Named
@ViewScoped
public class LivroBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private Livro livro = new Livro();

    private Integer autorId;

    private List<Livro> livros;

    @Inject
    private LivroDao livroDao;

    @Inject
    private AutorDao autorDao;

    public void setAutorId(Integer autorId) {
        this.autorId = autorId;
    }

    public Integer getAutorId() {
        return autorId;
    }

    public Livro getLivro() {
        return livro;
    }

    public List<Livro> getLivros() {
        if (this.livros == null) {
            this.livros = livroDao.listaTodos();
        }

        return livros;
    }

    public List<Autor> getAutores() {
        return autorDao.listaTodos();
    }

    public List<Autor> getAutoresDoLivro() {
        return this.livro.getAutores();
    }

    public void carregarLivroPelaId() {
        this.livro = livroDao.buscaPorId(this.livro.getId());
    }

    public void gravarAutor() {
        Autor autor = autorDao.buscaPorId(this.autorId);
        this.livro.adicionaAutor(autor);
        System.out.println("Escrito por: " + autor.getNome());
    }

    public void gravar() {
        System.out.println("Gravando livro " + this.livro.getTitulo());

        if (livro.getAutores().isEmpty()) {
            FacesContext.getCurrentInstance().addMessage("autor",
                    new FacesMessage("Livro deve ter pelo menos um Autor."));
            return;
        }

        if (this.livro.getId() == null) {
            livroDao.adiciona(this.livro);
            this.livros = livroDao.listaTodos();
        } else {
            livroDao.atualiza(this.livro);
        }

        this.livro = new Livro();
    }

    public void remover(Livro livro) {
        System.out.println("Removendo livro");
        livroDao.remove(livro);
    }

    public void removerAutorDoLivro(Autor autor) {
        this.livro.removeAutor(autor);
    }

    public void carregar(Livro livro) {
        System.out.println("Carregando livro");
        this.livro = livro;
    }

    public String formAutor() {
        System.out.println("Chamanda do formulário do Autor.");
        return "autor?faces-redirect=true";
    }

    public void comecaComDigitoUm(FacesContext fc, UIComponent component,
            Object value) throws ValidatorException {

        String valor = value.toString();
        if (!valor.startsWith("1")) {
            throw new ValidatorException(new FacesMessage(
                    "ISBN deveria começar com 1"));
        }

    }
}

```

public class LivroDao implements Serializable {

@Inject EntityManager manager;

private DAO <Livro> dao;

@PostConstruct void init() { this.dao = new DAO(this.manager, Livro.class); }

public List listaTodos() { return dao.listaTodos(); }

public Livro buscaPorId(Integer id) { return dao.buscaPorId(id); }

public void adiciona(Livro livro) { dao.adiciona(livro); }

public void atualiza(Livro livro) { dao.atualiza(livro); }

public void remove(Livro livro) { dao.remove(livro); }

}

2 respostas

Marcelo, você precisa usar algum mecanismo pra atualizar a página. Um bem bacana é o AJAX.

Você pode fazer assim:

<h:commandLink value="remove" action="#{livroBean.remover(livro)}">
    <f:ajax execute="@form" render="frmCadastrar" />
</h:commandLink>

A tag f:ajax faz uma solicitação assíncrona e renderiza (atualiza) partes específicas. A propriedade execute diz qual parte deve ser enviada ao servidor, nesse caso, o formulário inteiro. A propriedade render diz quais partes devem ser atualizadas após o retorno da solicitação assíncrona ao servidor, nesse caso, o elemento que possui o id frmCadastrar. Você pode renderizar quantos elementos quiser, bastando colocar os ids deles separados por espaço. Por exemplo, se quisesse renderizar um formulário de cadastro e outro de listagem seria algo assim:

<f:ajax execute="@form" render="frmCadastro frmListagem" />

Faz os testes aí e dá um retorno.

solução!

Já resolvi. Obrigado!

livro.xhtml

                    <p:column headerText="Remover">
                        <p:commandButton update="@form" process="@this" value="remover" actionListener="#{livroBean.remover(livro)}" icon="fa fa-fw fa-remove" />
                    </p:column>                                            

No LivroBean
    public void remover(Livro livro) {
        System.out.println("Removendo livro");
        this.livroDao.remove(livro);
        this.livros = this.livroDao.listaTodos();
    }

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software