Entendendo os processos / atualização de PrimeFaces e os atributos JSF f: ajax execute / render

O que exatamente são process e update em componentes PrimeFaces p:commandXxx e execute e render em tag f:ajax ?

Qual funciona no momento da validação? O que o atributo update faz em vez de atualizar o valor para o componente do backend? O process vincular o valor de atributo ao modelo? O que exatamente faz @this , @parent , @all e @form em ambos os atributos?

O exemplo abaixo está funcionando bem, mas estou um pouco confuso nos conceitos básicos.

 

O atributo do process é do lado do servidor e só pode afetar o EditableValueHolder UIComponent (campos de input) ou o ActionSource (campos de comando). O atributo process informa ao JSF, usando uma lista separada por espaços de IDs de clientes, cujos componentes devem ser processados ​​exatamente durante todo o ciclo de vida do JSF no envio de formulário (parcial).

O JSF aplicará os valores de solicitação (localizando o parâmetro de solicitação HTTP com base no ID do cliente do componente e configurando-o como valor enviado no caso de componentes EditableValueHolder ou enfileirando um novo ActionEvent no caso de componentes ActionSource ), realizar conversão, validação e atualização do valores do modelo (apenas para os componentes EditableValueHolder ) e, finalmente, invocam o ActionEvent enfileirado (somente para os componentes ActionSource ). O JSF ignorará o processamento de todos os outros componentes que não são cobertos pelo atributo de process . Além disso, os componentes cujo atributo rendered avaliado como false durante a fase de solicitação de solicitação de aplicação também serão ignorados como parte da proteção contra solicitações adulteradas.

Observe que, no caso de componentes ActionSource (como ), é muito importante include também o próprio componente no atributo de process , especialmente se você pretende invocar a ação associada ao componente. Portanto, o exemplo abaixo que pretende processar apenas determinados componentes de input quando um determinado componente de comando é chamado não funcionará:

   

Ele processaria apenas o #{bean.foo} e não o #{bean.action} . Você precisaria include o componente de comando também:

   

Ou, como você aparentemente descobriu, usando @parent se eles forem os únicos componentes que têm um pai comum:

     

Ou, se ambos forem os únicos componentes do componente UIForm pai, você também poderá usar @form :

     

Às vezes, isso é indesejável se o formulário contiver mais componentes de input que você deseja ignorar no processamento, mais frequentemente em casos em que deseja atualizar outro (s) componente (s) de input ou alguma seção da UI com base no componente de input atual. um método de ouvinte ajax. Você não quer que os erros de validação em outros componentes de input estejam impedindo que o método do ouvinte ajax seja executado.

Então há o @all . Isso não tem efeito especial no atributo de process , mas apenas no atributo de update . Um process="@all" se comporta exatamente como process="@form" . O HTML não suporta o envio de vários formulários de uma só vez.

Há também um @none que pode ser útil caso você não precise processar nada, mas quer atualizar algumas partes específicas via update , particularmente aquelas seções cujo conteúdo não depende de valores enviados ou ouvintes de ação. .

O equivalente padrão do JSF ao process específico do PrimeFaces é execute partir de . Ele se comporta exatamente da mesma maneira, exceto pelo fato de não suportar uma string separada por vírgula enquanto o PrimeFaces (apesar de eu pessoalmente recomendar apenas manter a convenção separada por espaço), nem a palavra-chave @parent . Além disso, pode ser útil saber que assume como padrão @form enquanto e assume como padrão @this . Finalmente, também é útil saber que o process suporta os chamados “Seletores PrimeFaces”, veja também Como funcionam os Seletores PrimeFaces como em update = “@ (.myClass)”?


O atributo update é do lado do cliente e pode afetar a representação HTML de todos os UIComponent s. O atributo update informa ao JavaScript (aquele responsável por manipular o pedido / resposta ajax), usando uma lista separada por espaço de IDs de clientes, cujas partes na tree DOM do HTML precisam ser atualizadas como resposta ao envio do formulário.

O JSF irá preparar a resposta correta do ajax para isso, contendo apenas as partes solicitadas para atualizar. O JSF irá ignorar todos os outros componentes que não são cobertos pelo atributo de update na resposta do ajax, mantendo a carga útil de resposta pequena. Além disso, os componentes cujo atributo rendered avaliado como false durante a fase de resposta da renderização serão ignorados. Observe que, embora retorne true , o JavaScript não pode atualizá-lo na tree DOM do HTML se ela fosse inicialmente false . Você precisaria envolvê-lo ou atualizar seu pai em vez disso. Veja também Ajax update / render não funciona em um componente que tenha renderizado o atributo .

Normalmente, você deseja atualizar apenas os componentes que realmente precisam ser “atualizados” no lado do cliente no envio de formulário (parcial). O exemplo abaixo atualiza todo o formulário pai via @form :

        

(note que o atributo process é omitido, já que o padrão é @form já)

Embora isso possa funcionar bem, a atualização dos componentes de input e comando é desnecessária neste exemplo específico. A menos que você altere os valores do modelo foo e bar dentro do método de action (o que seria, por sua vez, não intuitivo na perspectiva do UX), não há razão para atualizá-los. Os componentes da mensagem são os únicos que realmente precisam ser atualizados:

        

No entanto, isso fica tedioso quando você tem muitos deles. Essa é uma das razões pelas quais os Seletores PrimeFaces existem. Esses componentes de mensagens têm na saída HTML gerada uma class de estilo comum de ui-message , portanto, o seguinte também deve fazer:

        

(note que você deve manter os IDs nos componentes da mensagem, caso contrário o @(...) não funcionará! Novamente, veja Como funcionam os seletores do PrimeFaces como em update = “@ (.myClass)” para mais detalhes)

O @parent atualiza apenas o componente pai, que cobre o componente atual e todos os irmãos e seus filhos. Isso é mais útil se você tiver separado o formulário em grupos sãos com cada um de sua responsabilidade. O @this atualiza, obviamente, apenas o componente atual. Normalmente, isso é necessário apenas quando você precisa alterar um dos atributos HTML do componente no método de ação. Por exemplo

  

Imagine que o oncomplete precise trabalhar com o value que é alterado em action , então essa construção não teria funcionado se o componente não fosse atualizado, pela simples razão de que oncomplete é parte da saída HTML gerada (e, portanto, todas as expressões EL em lá são avaliados durante a resposta de renderização).

O @all atualiza todo o documento, que deve ser usado com cuidado. Normalmente, você gostaria de usar uma solicitação GET verdadeira para isso em vez de um link simples ( ou ) ou um redirecionamento após o POST por ?faces-redirect=true ou ExternalContext#redirect() . Em efeitos, process="@form" update="@all" tem exatamente o mesmo efeito que um envio não-ajax (não parcial). Em toda a minha carreira no JSF, o único caso de uso sensato que encontrei para @all é exibir uma página de erro inteira caso uma exceção ocorra durante uma solicitação de ajax. Veja também Qual é a maneira correta de lidar com as exceções do JSF 2.0 para componentes AJAXified?

O equivalente padrão do JSF à update específica do PrimeFaces é render partir de . Ele se comporta exatamente da mesma maneira, exceto pelo fato de não suportar uma string separada por vírgula enquanto o PrimeFaces (apesar de eu pessoalmente recomendar apenas manter a convenção separada por espaço), nem a palavra-chave @parent . Ambos update e render padrões para @none (que é “nada”).


Veja também:

  • Como descobrir o ID do cliente do componente para ajax update / render? Não é possível encontrar o componente com a expressão “foo” referenciada de “bar”
  • Ordem de execução de events ao pressionar PrimeFaces p: commandButton
  • Como diminuir a carga útil do pedido de p: ajax durante, por exemplo, p: dataTable pagination
  • Como mostrar detalhes da linha atual de p: dataTable no ap: dialog e atualizar após salvar
  • Como usar o na página JSF? Forma única? Múltiplas formas? Formulários nesteds?

Se você tem dificuldade em lembrar os valores padrão (eu sei que tenho …) aqui está um pequeno trecho da resposta da BalusC:

 Componente |  Submeter |  Atualizar
 ------------ |  --------------- |  --------------
 f: ajax |  execute = "@ this" |  render = "@ none"
 p: ajax |  process = "@ this" |  update = "@ nenhum"
 p: commandXXX |  process = "@ form" |  update = "@ nenhum"

Por processo (na especificação JSF é chamado de executar) você diz ao JSF para limitar o processamento ao componente que é especificado, tudo o mais é simplesmente ignorado.

update indica qual elemento será atualizado quando o servidor responder ao seu pedido.

@all : Todo componente é processado / renderizado.

@ this : O componente solicitante com o atributo de execução é processado / renderizado.

@form : O formulário que contém o componente solicitante é processado / renderizado.

@ pai: O pai que contém o componente solicitante é processado / renderizado.

Com o Primefaces você pode até usar seletores da JQuery, confira este blog: http://blog.primefaces.org/?p=1867