<p:commandXxx process> <p:ajax process> <f:ajax execute>
O processatributo é do lado do servidor e pode afetar apenas a UIComponentimplementação EditableValueHolder(campos de entrada) ou ActionSource(campos de comando). O processatributo informa ao JSF, usando uma lista separada por espaço de IDs do cliente, quais componentes exatamente devem ser processados durante todo o ciclo de vida do JSF após o envio do formulário (parcial).
O JSF aplicará os valores de solicitação (localizando o parâmetro de solicitação HTTP com base no próprio ID do cliente do componente e, em seguida, configurá-lo como valor enviado no caso de EditableValueHoldercomponentes ou enfileirar um novo ActionEventno caso de ActionSourcecomponentes), executar a conversão, validação e atualizar os valores do modelo ( EditableValueHoldersomente componentes) e, finalmente, invoque a fila ActionEvent( ActionSourcesomente componentes). O JSF ignorará o processamento de todos os outros componentes que não são cobertos por processatributo. Além disso, os componentes cujo renderedatributo é avaliado falsedurante a fase de aplicar valores de solicitação também serão ignorados como parte da proteção contra solicitações adulteradas.
Observe que, no caso de ActionSourcecomponentes (como <p:commandButton>), é muito importante incluir também o próprio componente no processatributo, principalmente se você pretende invocar a ação associada ao componente. Portanto, o exemplo abaixo, que pretende processar apenas determinados componentes de entrada quando um determinado componente de comando é chamado, não funcionará:
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="foo" action="#{bean.action}" />
Processaria apenas o #{bean.foo}e não o #{bean.action}. Você também precisará incluir o próprio componente de comando:
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="@this foo" action="#{bean.action}" />
Ou, como você aparentemente descobriu, usar @parentse eles forem os únicos componentes com um pai comum:
<p:panel><!-- Type doesn't matter, as long as it's a common parent. -->
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="@parent" action="#{bean.action}" />
</p:panel>
Ou, se os dois forem os únicos componentes do UIFormcomponente pai , você também poderá usar @form:
<h:form>
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="@form" action="#{bean.action}" />
</h:form>
Às vezes, isso é indesejável se o formulário contiver mais componentes de entrada que você gostaria de ignorar no processamento, mais frequentemente nos casos em que você gostaria de atualizar outro (s) componente (s) de entrada ou alguma seção da interface do usuário com base no componente de entrada atual em um método de ouvinte ajax. Você não quer que erros de validação em outros componentes de entrada estejam impedindo a execução do método do ouvinte ajax.
Então há o @all. Isso não tem efeito especial no processatributo, mas apenas no updateatributo. Um process="@all"comporta-se exatamente da mesma forma que process="@form". O HTML não suporta o envio de vários formulários ao mesmo tempo.
A propósito, também há um @noneque pode ser útil caso você não precise absolutamente processar nada, mas apenas deseja atualizar algumas partes específicas update, principalmente as seções cujo conteúdo não depende dos valores enviados ou dos ouvintes de ação.
Deve-se notar que o processatributo não tem influência na carga útil da solicitação HTTP (a quantidade de parâmetros da solicitação). Ou seja, o comportamento HTML padrão do envio de "tudo" contido na representação HTML do <h:form>não será afetado. Caso você tenha um formulário grande e deseje reduzir a carga útil da solicitação HTTP apenas para aqueles absolutamente necessários no processamento, ou seja, apenas aqueles cobertos pelo processatributo, é possível definir o partialSubmitatributo nos componentes do PrimeFaces Ajax como em <p:commandXxx ... partialSubmit="true">ou <p:ajax ... partialSubmit="true">. Você também pode configurar isso 'globalmente' editando web.xmle adicionando
<context-param>
<param-name>primefaces.SUBMIT</param-name>
<param-value>partial</param-value>
</context-param>
Como alternativa, você também pode usar o <o:form>OmniFaces 3.0+, cujo padrão é esse comportamento.
O JSF padrão equivalente ao específico do PrimeFaces processé executede <f:ajax execute>. Ele se comporta exatamente da mesma forma, exceto que não suporta uma cadeia de caracteres separada por vírgula enquanto a do PrimeFaces (embora eu pessoalmente recomendo apenas manter a convenção separada por espaço), nem a @parentpalavra - chave. Além disso, pode ser útil saber que o <p:commandXxx process>padrão é @formwhile <p:ajax process>e o <f:ajax execute>padrão é while @this. Por fim, também é útil saber que processsuporta os chamados "Seletores PrimeFaces", consulte também Como funcionam os seletores PrimeFaces, como em update = "@ (. MyClass)"?
<p:commandXxx update> <p:ajax update> <f:ajax render>
O updateatributo é do lado do cliente e pode afetar a representação HTML de todos os UIComponents. O updateatributo informa ao JavaScript (o responsável por manipular a solicitação / resposta do ajax), usando uma lista de IDs de clientes separada por espaço, cujas partes da árvore DOM do HTML precisam ser atualizadas como resposta ao envio do formulário.
O JSF preparará a resposta correta do ajax para isso, contendo apenas as partes solicitadas para atualização. O JSF ignorará todos os outros componentes que não são cobertos pelo updateatributo na resposta ajax, mantendo a carga útil da resposta pequena. Além disso, os componentes cujo renderedatributo é avaliado falsedurante a fase de resposta de renderização serão ignorados. Observe que, embora retorne true, o JavaScript não pode atualizá-lo na árvore DOM HTML, se fosse inicialmente false. Você precisaria envolvê-lo ou atualizar seu pai. Consulte também Ajax update / render não funciona em um componente que possui atributo de renderização .
Geralmente, você deseja atualizar apenas os componentes que realmente precisam ser "atualizados" no lado do cliente após o envio do formulário (parcial). O exemplo abaixo atualiza todo o formulário pai via @form:
<h:form>
<p:inputText id="foo" value="#{bean.foo}" required="true" />
<p:message id="foo_m" for="foo" />
<p:inputText id="bar" value="#{bean.bar}" required="true" />
<p:message id="bar_m" for="bar" />
<p:commandButton action="#{bean.action}" update="@form" />
</h:form>
(observe que o processatributo foi omitido, pois o padrão é @formjá)
Embora isso possa funcionar bem, a atualização dos componentes de entrada e comando é desnecessária neste exemplo específico. A menos que você altere os valores do modelo fooe o método barinterno action(o que por sua vez não seria intuitivo na perspectiva do UX), não há motivo para atualizá-los. Os componentes da mensagem são os únicos que realmente precisam ser atualizados:
<h:form>
<p:inputText id="foo" value="#{bean.foo}" required="true" />
<p:message id="foo_m" for="foo" />
<p:inputText id="bar" value="#{bean.bar}" required="true" />
<p:message id="bar_m" for="bar" />
<p:commandButton action="#{bean.action}" update="foo_m bar_m" />
</h:form>
No entanto, isso fica entediante quando você tem muitos deles. Essa é uma das razões pelas quais existem os seletores PrimeFaces. Esses componentes de mensagem têm na saída HTML gerada uma classe de estilo comum ui-message; portanto, o seguinte também deve ser:
<h:form>
<p:inputText id="foo" value="#{bean.foo}" required="true" />
<p:message id="foo_m" for="foo" />
<p:inputText id="bar" value="#{bean.bar}" required="true" />
<p:message id="bar_m" for="bar" />
<p:commandButton action="#{bean.action}" update="@(.ui-message)" />
</h:form>
(observe que você deve manter os IDs nos componentes da mensagem, caso contrário @(...)não funcionará! Mais uma vez, consulte Como funcionam os seletores do PrimeFaces como em update = "@ (. myClass)" funcionam? para obter detalhes)
Ele @parentatualiza apenas o componente pai, que cobre o componente atual e todos os irmãos e filhos. Isso é mais útil se você tiver separado o formulário em grupos sãos, cada um com sua própria responsabilidade. As @thisatualizações, obviamente, apenas o componente atual. Normalmente, isso é necessário apenas quando você precisa alterar um dos atributos HTML do componente no método action. Por exemplo
<p:commandButton action="#{bean.action}" update="@this"
oncomplete="doSomething('#{bean.value}')" />
Imagine que as oncompletenecessidades de trabalhar com as valuealterações foram alteradas action, então essa construção não funcionaria se o componente não fosse atualizado, pelo simples motivo de fazer oncompleteparte da saída HTML gerada (e, portanto, todas as expressões EL nele são avaliadas durante a resposta de renderização).
A @allatualiza todo o documento, que deve ser usado com cuidado. Normalmente, você deseja usar uma solicitação GET verdadeira para isso usando um link simples ( <a>ou <h:link>) ou um redirecionamento após o POST por ?faces-redirect=trueou ExternalContext#redirect(). Nos 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 @allé exibir uma página de erro na íntegra, caso ocorra uma exceção durante uma solicitação de ajax. Consulte também Qual é a maneira correta de lidar com exceções do JSF 2.0 para componentes AJAXified?
O JSF padrão equivalente ao específico do PrimeFaces updateé renderde <f:ajax render>. Ele se comporta exatamente da mesma forma, exceto que não suporta uma cadeia de caracteres separada por vírgula enquanto a do PrimeFaces (embora eu pessoalmente recomendo apenas manter a convenção separada por espaço), nem a @parentpalavra - chave. Ambos updatee o renderpadrão @noneé (que é "nada").
Veja também: