<p:commandXxx process> <p:ajax process> <f:ajax execute>
L' processattribut est côté serveur et ne peut affecter que l' UIComponentimplémentation EditableValueHolder(champs de saisie) ou ActionSource(champs de commande). L' processattribut indique à JSF, à l'aide d'une liste d'ID client séparés par des espaces, quels composants doivent être traités exactement tout au long du cycle de vie JSF lors de la soumission (partielle) du formulaire.
JSF appliquera ensuite les valeurs de la requête (recherche du paramètre de requête HTTP en fonction de l'ID client du composant, puis le définissant comme valeur soumise dans le cas des EditableValueHoldercomposants ou en mettant en file d'attente un nouveau ActionEventdans le cas des ActionSourcecomposants), effectuera la conversion, la validation et la mise à jour des valeurs du modèle ( EditableValueHoldercomposants uniquement) et enfin appeler la file d'attente ActionEvent( ActionSourcecomposants uniquement). JSF ignorera le traitement de tous les autres composants qui ne sont pas couverts par l' processattribut. De plus, les composants dont l' renderedattribut est évalué falsependant la phase d'application des valeurs de demande seront également ignorés dans le cadre de la protection contre les demandes altérées.
Notez que c'est dans le cas de ActionSourcecomposants (tels que <p:commandButton>) très importants que vous incluiez également le composant lui-même dans l' processattribut, en particulier si vous avez l'intention d'appeler l'action associée au composant. Ainsi, l'exemple ci-dessous qui vise à ne traiter que certains composants d'entrée lorsqu'un certain composant de commande est appelé ne fonctionnera pas:
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="foo" action="#{bean.action}" />
Il ne traiterait que le #{bean.foo}et non le #{bean.action}. Vous devrez également inclure le composant de commande lui-même:
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="@this foo" action="#{bean.action}" />
Ou, comme vous l'avez apparemment découvert, en utilisant @parents'ils sont les seuls composants ayant un parent commun:
<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, s'ils se trouvent tous deux être les seuls composants du UIFormcomposant parent , vous pouvez également utiliser @form:
<h:form>
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="@form" action="#{bean.action}" />
</h:form>
Cela n'est parfois pas souhaitable si le formulaire contient plus de composants d'entrée que vous souhaitez ignorer lors du traitement, plus que souvent dans les cas où vous souhaitez mettre à jour un ou plusieurs autres composants d'entrée ou une section d'interface utilisateur basée sur le composant d'entrée actuel dans une méthode d'écoute ajax. Vous ne voulez pas que des erreurs de validation sur d'autres composants d'entrée empêchent l'exécution de la méthode d'écoute ajax.
Ensuite, il y a le @all. Cela n'a aucun effet spécial dans l' processattribut, mais seulement dans l' updateattribut. A process="@all"se comporte exactement de la même manière que process="@form". De toute façon, HTML ne prend pas en charge la soumission de plusieurs formulaires à la fois.
Il y a d'ailleurs aussi un @nonequi peut être utile au cas où vous n'auriez absolument pas besoin de traiter quoi que ce soit, mais que vous ne vouliez mettre à jour que certaines parties spécifiques via update, en particulier les sections dont le contenu ne dépend pas des valeurs soumises ou des écouteurs d'action.
Il convient de noter que l' processattribut n'a aucune influence sur la charge utile de la requête HTTP (la quantité de paramètres de la requête). Cela signifie que le comportement HTML par défaut d'envoi de "tout" contenu dans la représentation HTML du <h:form>ne sera pas affecté. Si vous avez un formulaire volumineux et que vous souhaitez réduire la charge utile de la requête HTTP à ceux qui sont absolument nécessaires au traitement, c'est-à-dire uniquement ceux couverts par l' processattribut, vous pouvez définir l' partialSubmitattribut dans les composants PrimeFaces Ajax comme dans <p:commandXxx ... partialSubmit="true">ou <p:ajax ... partialSubmit="true">. Vous pouvez également configurer cela `` globalement '' en éditant web.xmlet en ajoutant
<context-param>
<param-name>primefaces.SUBMIT</param-name>
<param-value>partial</param-value>
</context-param>
Vous pouvez également utiliser <o:form>OmniFaces 3.0+ qui utilise par défaut ce comportement.
L'équivalent JSF standard du spécifique PrimeFaces processest executede <f:ajax execute>. Il se comporte exactement de la même manière, sauf qu'il ne prend pas en charge une chaîne séparée par des virgules, contrairement à PrimeFaces (bien que je recommande personnellement de s'en tenir à la convention séparée par des espaces), ni le @parentmot - clé. En outre, il peut être utile de savoir que la valeur par <p:commandXxx process>défaut est @formwhile <p:ajax process>et la valeur par <f:ajax execute>défaut @this. Enfin, il est également utile de savoir que processprend en charge les soi-disant "PrimeFaces Selectors", voir aussi Comment fonctionnent les PrimeFaces Selectors comme dans update = "@ (. MyClass)"?
<p:commandXxx update> <p:ajax update> <f:ajax render>
L' updateattribut est côté client et peut affecter la représentation HTML de tous les UIComponents. L' updateattribut indique à JavaScript (celui responsable de la gestion de la demande / réponse ajax), à l'aide d'une liste d'ID client séparés par des espaces, quelles parties de l'arborescence DOM HTML doivent être mises à jour en réponse à l'envoi du formulaire.
JSF préparera alors la bonne réponse ajax pour cela, contenant uniquement les parties demandées à mettre à jour. JSF ignorera tous les autres composants qui ne sont pas couverts par l' updateattribut dans la réponse ajax, gardant ainsi la charge utile de la réponse petite. De plus, les composants dont l' renderedattribut est évalué falsependant la phase de réponse de rendu seront ignorés. Notez que même s'il reviendrait true, JavaScript ne peut pas le mettre à jour dans l'arborescence DOM HTML s'il l'était initialement false. Vous auriez besoin de l'envelopper ou de mettre à jour son parent à la place. Voir aussi La mise à jour / le rendu Ajax ne fonctionne pas sur un composant qui a un attribut de rendu .
Habituellement, vous souhaitez mettre à jour uniquement les composants qui ont vraiment besoin d'être "rafraîchis" côté client lors de l'envoi (partiel) du formulaire. L'exemple ci-dessous met à jour l'ensemble du formulaire parent 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>
(notez que l' processattribut est omis car il est @formdéjà par défaut )
Bien que cela puisse fonctionner correctement, la mise à jour des composants d'entrée et de commande est dans cet exemple particulier inutile. À moins que vous ne changiez les valeurs du modèle fooet la méthode barinterne action(ce qui à son tour ne serait pas intuitif en perspective UX), il est inutile de les mettre à jour. Les composants du message sont les seuls qui doivent vraiment être mis à jour:
<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>
Cependant, cela devient fastidieux lorsque vous en avez beaucoup. C'est l'une des raisons pour lesquelles les PrimeFaces Selectors existent. Ces composants de message ont dans la sortie HTML générée une classe de style commune de ui-message, donc ce qui suit devrait également faire:
<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>
(notez que vous devez conserver les identifiants sur les composants de message, sinon @(...)cela ne fonctionnera pas! Encore une fois, voir Comment fonctionnent les sélecteurs PrimeFaces comme dans update = "@ (. myClass)"? pour plus de détails)
Les @parentmises à jour uniquement le composant parent, qui couvre ainsi le composant actuel et tous les frères et leurs enfants. Ceci est plus utile si vous avez séparé le formulaire en groupes sains avec chacun sa propre responsabilité. Les @thismises à jour, évidemment, que le composant actuel. Normalement, cela n'est nécessaire que lorsque vous devez modifier l'un des propres attributs HTML du composant dans la méthode d'action. Par exemple
<p:commandButton action="#{bean.action}" update="@this"
oncomplete="doSomething('#{bean.value}')" />
Imaginez que le oncompletebesoin de travailler avec le valuequi est modifié dans action, alors cette construction n'aurait pas fonctionné si le composant n'était pas mis à jour, pour la simple raison qui oncompletefait partie de la sortie HTML générée (et donc toutes les expressions EL présentes sont évaluées pendant la réponse de rendu).
Le @allmet à jour l'ensemble du document, qui doit être utilisé avec précaution. Normalement, vous aimeriez utiliser une vraie requête GET pour cela à la place soit par un simple lien ( <a>ou <h:link>), soit par une redirection après POST par ?faces-redirect=trueou ExternalContext#redirect(). En effet, process="@form" update="@all"a exactement le même effet qu'une soumission non ajax (non partielle). Dans toute ma carrière JSF, le seul cas d'utilisation raisonnable que j'ai rencontré @allest d'afficher une page d'erreur dans son intégralité au cas où une exception se produirait lors d'une requête ajax. Voir aussi Quelle est la bonne façon de traiter les exceptions JSF 2.0 pour les composants AJAXifiés?
L'équivalent JSF standard du spécifique PrimeFaces updateest renderde <f:ajax render>. Il se comporte exactement de la même manière, sauf qu'il ne prend pas en charge une chaîne séparée par des virgules, contrairement à PrimeFaces (bien que je recommande personnellement de s'en tenir à la convention séparée par des espaces), ni le @parentmot - clé. Les deux updateet prend la valeur par renderdéfaut @none(ce qui signifie «rien»).
Voir également: