<p:commandXxx process>
<p:ajax process>
<f:ajax execute>
O process
atributo é do lado do servidor e pode afetar apenas a UIComponent
implementação EditableValueHolder
(campos de entrada) ou ActionSource
(campos de comando). O process
atributo 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 EditableValueHolder
componentes ou enfileirar um novo ActionEvent
no caso de ActionSource
componentes), executar a conversão, validação e atualizar os valores do modelo ( EditableValueHolder
somente componentes) e, finalmente, invoque a fila ActionEvent
( ActionSource
somente componentes). O JSF ignorará o processamento de todos os outros componentes que não são cobertos por process
atributo. Além disso, os componentes cujo rendered
atributo é avaliado false
durante 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 ActionSource
componentes (como <p:commandButton>
), é muito importante incluir também o próprio componente no process
atributo, 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 @parent
se 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 UIForm
componente 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 process
atributo, mas apenas no update
atributo. 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 @none
que 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 process
atributo 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 process
atributo, é possível definir o partialSubmit
atributo 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.xml
e 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
é execute
de <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 @parent
palavra - chave. Além disso, pode ser útil saber que o <p:commandXxx process>
padrão é @form
while <p:ajax process>
e o <f:ajax execute>
padrão é while @this
. Por fim, também é útil saber que process
suporta 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 update
atributo é do lado do cliente e pode afetar a representação HTML de todos os UIComponent
s. O update
atributo 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 update
atributo na resposta ajax, mantendo a carga útil da resposta pequena. Além disso, os componentes cujo rendered
atributo é avaliado false
durante 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 process
atributo foi omitido, pois o padrão é @form
já)
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 foo
e o método bar
interno 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 @parent
atualiza 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 @this
atualizaçõ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 oncomplete
necessidades de trabalhar com as value
alterações foram alteradas action
, então essa construção não funcionaria se o componente não fosse atualizado, pelo simples motivo de fazer oncomplete
parte da saída HTML gerada (e, portanto, todas as expressões EL nele são avaliadas durante a resposta de renderização).
A @all
atualiza 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=true
ou 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
é render
de <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 @parent
palavra - chave. Ambos update
e o render
padrão @none
é (que é "nada").
Veja também: