PrimeFaces DataTable列属性对比:状态值映射失效求助
解决PrimeFaces DataTable状态列值映射问题
这个问题我之前也碰到过,核心原因是JSTL标签和JSF组件的执行生命周期不匹配,导致你的<c:if>判断永远不生效,所有情况都进入<c:otherwise>分支。
问题根源
JSTL的<c:if>、<c:choose>是在JSF的视图构建阶段执行的,而PrimeFaces DataTable中column.property的值是在视图渲染阶段才会被解析绑定的。当JSTL标签执行时,#{column.property}还没有被赋值,所以判断#{column.property == 'status'}永远为false,自然就走到了otherwise分支。
解决方案
这里提供三种实用的解决思路,你可以根据自己的场景选择:
方案1:用JSF的rendered属性替代JSTL
JSF组件的rendered属性是在视图渲染阶段执行的,和column.property的解析时机完全匹配,直接用两个<p:outputLabel>分别控制渲染逻辑即可:
<!-- 渲染status列的映射值 --> <p:outputLabel value="#{varTable.status == 0 ? 'active' : 'hidden'}" rendered="#{column.property == 'status'}" /> <!-- 渲染其他列的原始值 --> <p:outputLabel value="#{varTable[column.property]}" rendered="#{column.property != 'status'}" />
方案2:自定义转换器(推荐,复用性强)
如果这个状态映射逻辑需要在多个地方使用,自定义一个JSF转换器是更优雅的选择:
- 先编写转换器类:
@FacesConverter("statusConverter") public class StatusConverter implements Converter { // 页面回传值转对象(如果不需要回传可以简单实现) @Override public Object getAsObject(FacesContext context, UIComponent component, String value) { return "active".equals(value) ? 0 : 1; } // 对象转页面显示字符串 @Override public String getAsString(FacesContext context, UIComponent component, Object value) { if (value instanceof Integer) { int status = (Integer) value; return status == 0 ? "active" : "hidden"; } return value != null ? value.toString() : ""; } }
- 在DataTable的status列中使用这个转换器:
<p:column headerText="status" property="status"> <p:outputLabel value="#{varTable.status}" converter="statusConverter" /> </p:column>
方案3:直接在EL表达式中嵌套判断(适合简单场景)
如果只是单一页面使用,也可以直接在value属性里用EL表达式完成判断,省去额外标签:
<p:outputLabel value="#{column.property == 'status' ? (varTable[column.property] == 0 ? 'active' : 'hidden') : varTable[column.property]}" />
总结
优先推荐方案2(转换器),它的复用性和可维护性最好;如果是临时的单一页面需求,方案1或3会更快捷。
内容的提问来源于stack exchange,提问作者Trương Huy
相关产品推荐
相关产品推荐

