Como ajax-refresh dynamic include content pelo menu de navegação? (JSF SPA)

Estou aprendendo apenas o JSF 2 graças a este site que aprendi muito em tão pouco tempo.

Minha pergunta é sobre como implementar um layout comum a todas as minhas páginas do JSF 2 e ter apenas a parte do conteúdo da página atualizada não toda a página sempre que eu clicar em um link / menu de um painel diferente. Eu estou usando a abordagem Facelets que faz o que eu quero, exceto que cada vez que eu clico em um link de um painel (por exemplo, itens de menu do painel esquerdo) toda a página é atualizada. O que estou procurando é uma maneira de atualizar apenas a parte de conteúdo da minha página. Para ilustrar isso abaixo, está meu pagelayout de destino.

insira a descrição da imagem aqui Não postou meu código porque não tenho certeza se o Facelets pode fazer isso. Existe outra abordagem mais adequada para minha exigência que não seja o Facelets?

Uma abordagem direta seria a seguinte visão:

 

Header

Com esse bean:

 @ManagedBean @ViewScoped public class Bean implements Serializable { private String page; @PostConstruct public void init() { page = "include1"; // Default include. } // +getter+setter. } 

Neste exemplo, os modelos de inclusão reais são include1.xhtml , include2.xhtml e include3.xhtml na include3.xhtml /WEB-INF/includes (a pasta e o local são totalmente gratuitos à sua escolha; os arquivos são colocados apenas em /WEB-INF em para impedir o access direto , adivinhando o URL na barra de endereço do navegador).

Esta abordagem funciona em todas as versões do MyFaces, mas requer um mínimo de Mojarra 2.3.0. Caso você esteja usando uma versão do Mojarra anterior à versão 2.3.0, tudo isso falhará quando a página contiver um . Qualquer postback falhará porque está totalmente ausente do estado de exibição. Você pode resolver isso fazendo o upgrade para o minimamente Mojarra 2.3.0 ou com um script encontrado nesta resposta h: commandButton / h: o commandLink não funciona no primeiro clique, funciona apenas no segundo clique ou se você já estiver usando a biblioteca do utilitário JSF OmniFaces , use seu script FixViewState . Ou, se você já estiver usando PrimeFaces e usar exclusivamente o ajax, ele já será considerado de forma transparente.

Além disso, certifique-se de usar minimamente o Mojarra 2.1.18, pois versões mais antigas falharão mantendo vivo o bean com escopo de visão, fazendo com que a inclusão incorreta seja usada durante o postback. Se você não puder atualizar, precisará retornar à abordagem abaixo (relativamente desajeitada) de renderização condicional da exibição, em vez de construir condicionalmente a exibição:

 ...            

A desvantagem é que a exibição se tornaria relativamente grande e que todos os beans gerenciados associados poderiam ser inicializados desnecessariamente, mesmo quando não fossem usados ​​de acordo com a condição renderizada.

Quanto ao posicionamento dos elementos, é apenas uma questão de aplicar o CSS certo. Isso está além do escopo do JSF 🙂 Pelo menos, renderiza um

, de modo que deve ser bom o suficiente.

Por último mas não menos importante, esta abordagem SPA (Single Page Application) não é SEO amigável. Todas as páginas não são indexáveis ​​por searchbots nem podem ser marcadas por endusers, você pode precisar mexer com o histórico de HTML5 no cliente e fornecer um fallback do lado do servidor. Além disso, no caso de páginas com formulários, a mesma instância do bean de escopo de visão seria reutilizada em todas as páginas, resultando em um comportamento de escopo não intuitivo quando você navega de volta para uma página visitada anteriormente. Eu sugeriria ir com a abordagem de templates, como descrito na segunda parte desta resposta: Como include outro XHTML em XHTML usando o JSF 2.0 Facelets? Veja também Como navegar no JSF? Como fazer o URL refletir a página atual (e não a anterior) .

Se você quiser apenas atualizar parte da página, existem apenas duas maneiras de ir (para a web em geral, não apenas para o JSF). Você tem que usar frameworks ou Ajax. O JSF 2 suporta ajax nativamente, confira a tag f: ajax para atualizar apenas 1 componente sem recarregar a página inteira.

O Netbeans fornece um assistente que cria o layout proposto com o mínimo de esforço usando o JSF. Então, a melhor maneira de começar é dar uma olhada no Facelets Template Wizard e olhar a fonte gerada.