primefaces uiViewRoot在<p:datatable> </p:datatable>中找到组件

时间:2012-05-15 05:29:26

标签: jsf datatable primefaces components

我正在使用primefaces 3.2。

我遇到以下情况:

<h:form id="someForm">
  ..
  <p:dataTable id="someDataTable" value="#{BackingBean.list}" var="element" ..>
    <p:column>
      <p:calendar id="someCalendar" value=#{element.date} ../>
      <p:message id="someCalendarMessage" for=":someForm:someDataTable:someCalendar"/>
    <p:column>
  </p:dataTable>    
  ..
</h:form>

动态更新“someDataTable”,然后将所有数据提交给服务器端。在支持bean中,如果输入的日期不满足某些条件,我想发送日历“someCalendar”的消息。我尝试使用此代码找到组件:

FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.addMessage(facesContext.getViewRoot().findComponent(":someForm:someDataTable:" + "i" + ":someCalendar").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, Utils.getResourceBundleString("dictionary", "error") + ":", Utils.getResourceBundleString("dictionary", "some_message")));
return;

其中i是dataTable中“元素”的索引,它与位于BackingBean中的列表中的索引相同。

问题是我得到NullPointerException,因为facesContext.getViewRoot()。findComponent(..)方法找不到组件,虽然我检查了视图中生成的日历的id,它是 :someForm:someDataTable:0:someCalendar表示第一个元素,它应该是:someForm:someDataTable:1:someCalendar用于下一个元素等。

为什么facesContext.getViewRoot()。findComponent(..)方法无法找到里面的组件?它是动态更新的,也许服务器端在提交完成后没有获得更新的组件树?

提前致谢。

1 个答案:

答案 0 :(得分:3)

这是因为p:dataTable是重复的组件,在视图构建期间,视图根目录中只有一个日历。它的标识为someForm:someDataTable:someCalendar

仅在视图渲染时间内创建表行并生成依赖于行的ID。

您应该使用JSF内置验证工具来检查您的日期:

在视图中:

<p:calendar id="someCalendar" value=#{element.date} 
            validator="#{BackinBean.validateDate}"/>
<p:message id="someCalendarMessage" for="someCalendar"/>

someCalendar属性中for就足够了)

并在支持bean中:

public void validateDate(
               FacesContext context, 
               UIComponent component, 
               Object value) throws ValidatorException {

        if (/* date is not valid */) {
            throw new ValidatorException(
               new FacesMessage("Date is not valid"));
        }

}

验证方法中的FacesMessage将自动显示在正确的表格行中。