Tags JSTL sont taghandlers et ils sont exécutés au cours de visualiser le temps de construction, tandis que le JSF composants de l'INTERFACE utilisateur sont exécutées au cours d' afficher les temps de rendu. Notez que JSF propre <f:xxx>
et <ui:xxx>
balises qui ne sont pas étendre UIComponent
(c'est à dire tout sauf de l' <f:param>
et <f:selectItem(s)>
et toutes ces balises ayant un rendered
attribut) sont également taghandlers. Aussi, l' id
et binding
attributs de JSF composants de l'INTERFACE utilisateur sont évalués pendant les temps de construction. Ainsi, la réponse ci-dessous s'applique à eux aussi.
Le point de vue du temps de compilation est ce moment où le XHTML/fichier JSP est d'être analysés et convertis à un composant JSF arbre, qui est ensuite stocké comme UIViewRoot
de la FacesContext
. Le point de vue le temps de rendu est le moment où le JSF composant de l'arbre est sur le point de générer des pages HTML, en commençant par UIViewRoot#encodeAll()
. Donc: JSF composants de l'INTERFACE utilisateur et les balises JSTL ne pas fonctionner en synchronisation que vous vous attendez de la codification. Vous pouvez le visualiser comme suit: JSTL fonctionne de haut en bas en premier, la production de la JSF composant de l'arbre, alors il est JSF tour à courir à partir du haut vers le bas encore une fois, la production de la sortie HTML.
Par exemple, ce Facelets balisage itération sur 3 éléments à l'aide d' <c:forEach>
:
<c:forEach items="#{bean.items}" var="item">
<h:outputText id="item_#{item.id}" value="#{item.value}" />
</c:forEach>
...crée pendant les temps de construction de trois <h:outputText>
composants dans le programme JSF composant de l'arbre, à peu près représentés comme ceci:
<h:outputText id="item_#{bean.items[0].id}" value="#{bean.items[0].value}" />
<h:outputText id="item_#{bean.items[1].id}" value="#{bean.items[1].value}" />
<h:outputText id="item_#{bean.items[2].id}" value="#{bean.items[2].value}" />
...qui à son tour individuellement générer leur code HTML de sortie pendant les temps de rendu:
<span id="item_1">value1</span>
<span id="item_2">value2</span>
<span id="item_3">value3</span>
(notez que vous devez manuellement assurer de l'unicité des Id composant)
Tout ce Facelets balisage itération sur 3 éléments à l'aide d' <ui:repeat>
:
<ui:repeat id="items" value="#{bean.items}" var="item">
<h:outputText id="item" value="#{item.value}" />
</ui:repeat>
...se termine déjà en place dans le cadre du programme composant de l'arbre par lequel le même <h:outputText>
composant est pendant les temps de rendu étant réutilisé pour générer du code HTML de sortie basée sur l'itération courante ronde:
<span id="items:0:item">value1</span>
<span id="items:1:item">value2</span>
<span id="items:2:item">value3</span>
(notez que l' <ui:repeat>
comme NamingContainer
composant d'ores et déjà assuré de l'unicité de l'IDENTIFIANT client basée sur l'itération de l'index; il n'est également pas possible d'utiliser EL en id
attribut de cette façon, il est également évaluée lors de l'affichage de temps de construction tout en #{item}
est disponible uniquement pendant les temps de rendu)
Tout cela peut conduire à des résultats inattendus lors de l'utilisation de balises JSTL comme <c:forEach>
, <c:if>
, etc à l'intérieur de JSF itération des composants tels que <h:dataTable>
, <ui:repeat>
, etc, ou lors de la JSTL attributs de la balise dépendent des résultats de JSF événements tels que preRenderView
ou soumises par le formulaire de valeurs dans le modèle, qui ne sont pas disponibles pendant les temps de construction.
Aussi, Mojarra versions plus anciennes que 2.1.18 avait un bug dans la partielle de l'etat d'économie lorsque le référencement d'une vue étendue de haricot dans un JSTL attribut de balise. L'ensemble de la vue étendue de haricot serait nouvellement recréé au lieu de l'extrait de l'arbre d'affichage (tout simplement parce que la vue complète de l'arbre n'est pas encore disponible au moment de JSTL). Si vous êtes enceinte ou le stockage d'une partie de l'état dans la vue étendue de haricot par un JSTL attribut de balise, il n'y aura pas de retour de la valeur que vous attendez, ou il sera "perdu" dans la vue réelle étendue de haricot qui est restauré après le point de vue de l'arbre est construit.
En un mot: l'Utilisation de balises JSTL pour contrôler le flux de JSF composant de l'arbre de construction. Utiliser JSF composants de l'INTERFACE utilisateur pour contrôler le flux de sortie HTML génération. Ne pas lier l' var
d'itération des composants JSF de JSTL attributs de la balise. Ne comptez pas sur JSF événements dans JSTL attributs de la balise. Utiliser au moins Mojarra 2.1.18 avoir le poulet-oeuf question à portée de vue fixe, sinon, vous devez désactiver partielle de l'etat d'économie en web.xml
.
Voir aussi:
Pour voir quelques exemples dans le monde réel où les balises JSTL sont utiles (c'est à dire quand les, correctement utilisés lors de la construction de la vue), voir la suite de questions/réponses:
Pour votre béton à l'exigence fonctionnelle, si vous souhaitez rendre les composants JSF, sous certaines conditions, l'utilisation de l' rendered
d'attribut sur le JSF composant HTML au lieu de cela, particulièrement si #{lpc}
représente actuellement réitéré au point d'un programme d'ACI itération composant tel qu' <h:dataTable>
.
<h:someComponent rendered="#{lpc.verbose}">
...
</h:someComponent>
Voir aussi: