Comprendre les processus/mises à jour de PrimeFaces et les attributs JSF f:ajax execute/render

que sont exactement process et update dans PrimeFaces p:commandXxx composants et execute et render dans f:ajax étiquette?

Qui fonctionne au moment de la validation? Que fait l'attribut update au lieu de mettre à jour la valeur vers le composant à partir de la fin? L'attribut process lie-t-il la valeur au modèle? Que faire exactement? @this , @parent , @all et @form dans les deux attributs?

l'exemple ci-dessous fonctionne bien, mais je suis un peu confus dans les concepts de base.

<p:commandButton process="@parent"
                 update="@form"
                 action="#{bean.submit}" 
                 value="Submit" />
163
demandé sur BalusC 2014-08-16 14:02:07

3 réponses

<p:commandXxx process> <p:ajax process> <f:ajax execute>

l'attribut process est côté serveur et ne peut affecter que UIComponent s implémentation EditableValueHolder (champs d'entrée) ou ActionSource (champs de commande). L'attribut process indique à JSF, à l'aide d'une liste d'identificateurs de clients séparés par des espaces, quels composants exactement doivent être traités tout au long du cycle de vie de JSF. (partielle) formulaire de soumission.

JSF appliquera alors les valeurs de requête (trouver le paramètre de requête HTTP basé sur l'ID client du composant et ensuite soit le Définir comme valeur soumise dans le cas des composants EditableValueHolder , soit faire la queue pour un nouveau ActionEvent dans le cas des composants ActionSource ), effectuera la conversion, la validation et la mise à jour des valeurs du modèle (composants EditableValueHolder uniquement) et finalement invoquer la mise en file d'attente ActionEvent ( ActionSource composants uniquement). JSF sautera le traitement de tous les autres composants qui ne sont pas couverts par l'attribut process . De plus, les composants dont l'attribut rendered est évalué à false pendant la phase des valeurs de requête apply seront également omis dans le cadre de la protection contre les requêtes altérées.

notez que c'est dans le cas de ActionSource composants (tels que <p:commandButton> ) très important que vous incluez également le composant lui-même dans le process attribut, en particulier si vous avez l'intention d'invoquer l'action associée à la composante. Ainsi, l'exemple ci-dessous qui prévoit de ne traiter que certains composants d'entrée lorsqu'un certain composant de commande est invoqué ne fonctionnera pas:

<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="foo" action="#{bean.action}" />

il ne traiterait que les #{bean.foo} et et non le #{bean.action} . Vous devez 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 apparemment découvert, en utilisant @parent s'ils se trouvent être 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 les deux être les seuls composants du parent "15191190920 UIForm composant, alors vous pouvez également utiliser @form :

<h:form>
    <p:inputText id="foo" value="#{bean.foo}" />
    <p:commandButton process="@form" action="#{bean.action}" />
</h:form>

ceci est parfois indésirable si le formulaire contient plus de composants d'entrée que vous souhaitez sauter dans le traitement, plus que souvent dans les cas où vous souhaitez mettre à jour un autre composant d'entrée ou une section D'interface basée sur le composant d'entrée courant dans une méthode d'écoute ajax. Vous notamment ne voulez pas que les erreurs de validation sur les autres composants d'entrée empêchent la méthode d'écoute ajax d'être exécutée.

puis il y a le @all . Cela n'a pas d'effet particulier dans l'attribut process , mais seulement dans l'attribut update . Un process="@all" se comporte exactement comme un process="@form" . HTML ne fonctionne pas support soumettre plusieurs formulaires à la fois de toute façon.

il y a d'ailleurs aussi un @none qui peut être utile dans le cas où vous n'avez absolument pas besoin de traiter quoi que ce soit, mais seulement veulent mettre à jour certaines parties spécifiques via update , en particulier les sections dont le contenu ne dépend pas des valeurs soumises ou des auditeurs d'action.

doit être noté que l'attribut process a no influence sur la charge utile de la requête HTTP (le montant des paramètres de la requête). Autrement dit, le comportement HTML par défaut de l'envoi de "tout" contenu dans la représentation HTML du <h:form> ne sera pas affecté. Dans le cas où vous avez un grand formulaire, et que vous voulez réduire la charge utile de la requête HTTP à seulement ceux absolument nécessaires dans le traitement, c'est-à-dire seulement ceux couverts par l'attribut process , alors vous pouvez définir l'attribut partialSubmit dans les composants Ajax PrimeFaces comme dans <p:commandXxx ... partialSubmit="true"> ou <p:ajax ... partialSubmit="true"> . Alternativement, vous pouvez également utiliser <o:form> de OmniFaces 3.0+ qui par défaut à ce comportement.

le JSF standard équivalent aux PrimeFaces spécifiques process est execute de <f:ajax execute> . Il se comporte exactement de la même façon sauf qu'il ne supporte pas une chaîne séparée par des virgules alors que les PrimeFaces le font (bien que je recommande personnellement de simplement s'en tenir à la convention séparée par des espaces), ni le mot-clé @parent . En outre, il peut être utile de savoir que <p:commandXxx process> par défaut à @form tandis que <p:ajax process> et <f:ajax execute> par défaut à @this . Enfin, il est également utile de savoir que process supporte les sélecteurs dits "PrimeFaces", voir aussi Comment faire les sélecteurs de PrimeFaces comme dans update="@(.myClass) " travail?


<p:commandXxx update> <p:ajax update> <f:ajax render>

l'attribut update est côté client et peut affecter la représentation HTML de tous les UIComponent s. L'attribut update indique à JavaScript (celui qui est responsable du traitement de la requête/réponse ajax), à l'aide d'une liste d'IDs de client séparés par des espaces, quelles parties de L'arborescence HTML DOM doivent être mises à jour en réponse au formulaire submit.

JSF préparera alors la réponse ajax droite pour cela, contenant seulement le pièces à mettre à jour. JSF sautera tous les autres composants qui ne sont pas couverts par l'attribut update dans la réponse ajax, gardant ainsi la charge utile de la réponse petite. De plus, les composants dont l'attribut rendered est évalué à false pendant la phase de réponse du rendu seront omis. Notez que même si elle retournerait true , JavaScript ne peut pas la mettre à jour dans L'arbre des DOM HTML si elle était initialement false . Vous devez l'envelopper ou mettre à jour son parent à la place. Voir aussi Ajax update / render ne fonctionne pas sur un composant qui a rendu l'attribut .

habituellement, vous souhaitez mettre à jour seulement les composants qui vraiment ont besoin d'être" rafraîchis " du côté du client sur le formulaire (partiel) soumettre. L'exemple ci-dessous met à jour le formulaire parent entier 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'attribut process est omis en tant que par défaut @form déjà)

bien que cela puisse fonctionner correctement, la mise à jour des composants d'entrée et de commande n'est pas nécessaire dans cet exemple particulier. A moins que vous ne changiez les valeurs du modèle foo et bar à l'intérieur de la méthode action (ce qui serait à son tour peu intuitif en perspective UX), il n'y a pas de raison de les mettre à jour. Les composants de message sont les seuls que vraiment doivent ê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 quand vous avez beaucoup d'entre eux. C'est l'une des raisons pour lesquelles les sélecteurs PrimeFaces existent. Ces composants de message ont dans la sortie HTML générée une classe de style commun de ui-message , de sorte que 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 garder les ID sur les composants de message, sinon @(...) ne fonctionnera pas! Encore une fois, voir comme dans la mise à jour="@(.myClass) " travail? pour le détail)

le @parent ne met à jour que la composante parentale, qui couvre donc la composante actuelle ainsi que tous les frères et sœurs et leurs enfants. Ceci est plus utile si vous avez séparé la forme dans des groupes sains avec chacun sa propre responsabilité. Le @this ne met à jour, évidemment, que le composant courant. Normalement, cela n'est nécessaire que lorsque vous devez changer L'un des HTML du composant attributs dans la méthode action. Par exemple:

<p:commandButton action="#{bean.action}" update="@this" 
    oncomplete="doSomething('#{bean.value}')" />

Imaginez que le oncomplete doit fonctionner avec le value qui est modifié dans action , alors cette construction n'aurait pas fonctionné si le composant n'avait pas été mis à jour, pour la simple raison que oncomplete fait partie de la sortie HTML générée (et donc toutes les expressions EL dans ce cas sont évaluées pendant la réponse de rendu).

le @all met à jour l'ensemble du document, qui doit être utilisé avec précaution. Normalement, vous souhaitez utiliser une requête true GET pour ceci à la place par un lien simple ( <a> ou <h:link> ) ou une redirection-après-poste par ?faces-redirect=true ou 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é pour @all est d'afficher une page d'erreur dans son intégralité au cas où une exception se produit lors d'une demande ajax. Voir aussi Quelle est la bonne façon de traiter les exceptions JSF 2.0 pour les composants Ajaxifiés?

le JSF standard équivalent aux PrimeFaces spécifiques update est render de <f:ajax render> . Il se comporte exactement de la même façon sauf qu'il ne supporte pas une chaîne séparée par des virgules alors que les PrimeFaces le font (bien que je recommande personnellement de simplement s'en tenir à la convention séparée par l'espace), ni le mot-clé @parent . À la fois update et render par défaut à @none (qui est,"rien").


Voir aussi:

251
répondu BalusC 2018-09-25 14:24:20

si vous avez du mal à vous souvenir des valeurs par défaut (je sais que je l'ai... voici un court extrait de la réponse de BalusC:

Component    | Submit          | Refresh
------------ | --------------- | --------------
f:ajax       | execute="@this" | render="@none"
p:ajax       | process="@this" | update="@none"
p:commandXXX | process="@form" | update="@none"
47
répondu Jaqen H'ghar 2017-07-26 21:38:09

par processus (dans la spécification JSF c'est appelé execute) vous dites JSF pour limiter le traitement au composant qui sont spécifiés chaque autre chose est juste ignorée.

update indique quel élément sera mis à jour lorsque le serveur répondra à votre demande.

@tous : chaque composant est traité/Rendu.

@ce : le composant requérant avec l'exécution attribut est traité / Rendu.

@"formulaire de 151960920" : le formulaire qui contient Le requérant est traité/rendu.

@parent : le parent qui contient le composant requérant est traité/Rendu.

avec Primefaces, vous pouvez même utiliser des sélecteurs JQuery, consultez ce blog: http://blog.primefaces.org/?p=1867

21
répondu faissalb 2014-08-16 12:22:47