JSF 2.0和JSTL使用c:set标签来存储一些临时数据

egl*_*ter 5 jstl primefaces jsf-2

我正在使用JSF 2.0(mojarra)+ primefaces开发一个Web应用程序.在过去,我成功地使用了jstl库的[c:set]标签来存储一些临时数据或从其他标签输出.

在我目前的情况下,我想再次使用它,但它不能正常工作,我不知道为什么.在下面的例子中它起作用但特别有效.为什么案例2不能正常工作?

<h:form id="userAdministration">
  <p:messages id="messages" showDetail="true" />
  <p:dataTable id="userTable" selectionMode="single" var="user" value="#{users}">
    <p:column>
      <f:facet name="header">
        <h:outputText value="#{message.user_table_header_id_column}" />
      </f:facet>
      <h:outputText value="#{user.id}" />
    </p:column>

    <p:column>
      <f:facet name="header">
        <h:outputText value="#{message.global_table_header_action_column}" />
      </f:facet>
      <p:commandButton type="push" onclick="#{user.loginname}DeleteConfirmation.show()" value="#{message.global_table_action_delete}" image="ui-icon-trash">
        <f:setPropertyActionListener value="#{user}" target="#{userAdministrationController.selectedUser}" />
      </p:commandButton>
      <!-- 1. WORKS FINE, STORED VALUE IS "loginname" -->
      <c:set var="deleteConfirmationMessage" value="#{user.loginname}"></c:set>
      <!-- 2. VALUE IS "!!!" AND NOT "loginname !!!" -->
      <c:set var="deleteConfirmationMessage2">
        <h:outputText value="#{user.loginname}" />!!!
      </c:set>
      <!-- 3. WORKS FINE (OUTPUT "loginname") -->
      <h:outputText value="#{user.loginname}" />
      <p:confirmDialog  message="#{deleteConfirmationMessage}" header="#{message.user_dialog_delete_confirmation_title}" severity="alert" widgetVar="#{user.loginname}DeleteConfirmation">
        <p:commandButton value="#{message.user_dialog_delete_confirmation_no}" onclick="#{user.loginname}DeleteConfirmation.hide()" update="@form" type="button" /> 
      </p:confirmDialog>
    </p:column>
Run Code Online (Sandbox Code Playgroud)

Bal*_*usC 7

为什么案例2不能正常工作?

 <!-- 2. VALUE IS "!!!" AND NOT "loginname !!!" -->
 <c:set var="deleteConfirmationMessage2">
   <h:outputText value="#{user.loginname}" />!!!
 </c:set>
Run Code Online (Sandbox Code Playgroud)

那是因为标签处理程序和UI组件不能同时运行.JSTL标记是标记处理程序,它们在构建视图期间运行(当XHTML文件转换为JSF组件树时).JSF <h:xxx>标记是UI组件,它们在呈现视图期间运行(当JSF组件树被转换/呈现为HTML代码时).另请参阅JSF2 Facelets中的JSTL ......有意义吗?

所以,当<c:set>跑步时,<h:outputText>根本没有跑.

但在这个特殊的构造中,你根本不需要它<h:outputText>.除了将其设置value<c:set>,你也可以只内嵌的EL表达式的模板文本生(注意,这使用JSF时的Facelets,JSF使用时不与JSP工程;鉴于你使用PrimeFaces,你"肯定使用Facelets,因为PrimeFaces根本没有JSP taglib.

 <c:set var="deleteConfirmationMessage2">
   #{user.loginname}!!!
 </c:set>
Run Code Online (Sandbox Code Playgroud)

或者你可能不知道你可以在一个属性中混合使用EL和普通字符串

 <c:set var="deleteConfirmationMessage2" value="#{user.loginname}!!!" />
Run Code Online (Sandbox Code Playgroud)

要么

<p:confirmDialog  message="#{user.loginname}!!!">
Run Code Online (Sandbox Code Playgroud)

根据具体的功能要求,从问题中不完全清楚,不同的替代方案可能是使用OmniFaces<o:cache>组件.如果您打算为更广泛的范围缓存值,而不仅仅像页面/请求范围一样,这可能会更有用.<c:set>


JOT*_*OTN 1

只是做出有根据的猜测,因为我没有尝试将 JSF 和 JSTL 结合起来,但我相信 c:set 将在 h:outputText 呈现之前处理,因此它只会看到其正文中的静态文本。我不确定与 JSF 生命周期相关的标签处理程序的调用顺序,但添加一些日志记录可以解决这个问题。