首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在JSF中访问动态UIComponents

在JSF中访问动态UIComponents
EN

Stack Overflow用户
提问于 2013-09-02 12:21:33
回答 1查看 10.2K关注 0票数 3

我有一个JSF页面,在这个页面中,我在<h:dataTable>中迭代一个列表,以显示一些包含复选框、一些文本和一个文本框的行。

我必须验证<h:dataTable>,以便当用户选中复选框时,他必须在文本框中输入一些文本。

这是我的JSF页面。

代码语言:javascript
复制
 <h:form prependId="false" id="form">
    <h:dataTable id="rm" width="100%" cellspacing="4"
    value="#{controller.alertTriggers}" var="alt"
        columnClasses="c1,c2,c3,c4">                    


            <h:column>
              <h:selectBooleanCheckbox value="#{alt.checkValue}" id="checkbox"/>
           </h:column>
            <h:column>
               <h:outputText value="#{alt.id}" />                                       
            </h:column>
            <h:column>
              <h:outputFormat value="#{alt.msg1}" />                              
            </h:column>
            <h:column>                                              
                 <h:message for="emailID" id="email" styleClass="validation-error"/>
                 <h:inputText value="#{alt.mailId}" id="emailID" style="width: 87%;" />

            </h:column>                                         

    </h:dataTable>                                          
</h:form>                                       

我给出了所有复选框的id为checkbox,所有文本框的id为emailID。当呈现页面时,在检查页面源时,我发现复选框的ids是‘rm:0:复选框’,‘rm:1:复选框’.这些文本框是“rm:0:emailID”,“rm:1:emailID”。

在控制器中,我希望访问使用以下代码的这些动态文本框和复选框:

代码语言:javascript
复制
 FacesContext context = FacesContext. getCurrentInstance();


                  for (int i=0;i<9;i++){
                       UIInput u=(UIInput) FacesContext.getCurrentInstance().getViewRoot().findComponent( "form:rm:" +i+":checkbox" );
                        if ((Boolean) u.getValue()){
                              UIInput ui=(UIInput) FacesContext.getCurrentInstance().getViewRoot().findComponent( "form:rm:" +i+":emailID" );

                               //code

                       }
                 }

但这给了java.lang.NullPointerException

即使使用代码:

代码语言:javascript
复制
  UIInput u=(UIInput) FacesContext.getCurrentInstance().getViewRoot().
   findComponent( "form:rm:0:checkbox" ); gives the same exception.

但如果我用

代码语言:javascript
复制
     UIInput u=(UIInput) FacesContext.getCurrentInstance().getViewRoot().
       findComponent( "form:rm:checkbox" );

它没有给出一个空指针异常,但我不知道它是否给出了哪个复选框的值。

所以,总之,

JSF以rm:1:复选框、rm:2:复选框等形式生成it,但是当我试图访问JSF中的这个UI组件时,我无法这样做.

我漏掉了什么吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-09-02 12:51:31

FacesContext#getViewRoot()返回JSF组件树。在考虑了所有taghandlers (JSTL、<ui:include>等)之后,这就是XHTML源代码所表示的完全相同的树。您需要认识到,其中只有一个 <h:selectBooleanCheckbox id="checkbox">。它在UIViewRoot#findComponent()中是可用的,确切的ID是"form:rm:checkbox"

它只是它的HTML表示,根据父<h:dataTable>的当前迭代周期多次重新生成。此生成的HTML表示形式反过来具有带有当前行索引内联的客户端in。这种HTML表示显然在组件树中不可用。

组件的状态(提交的值等)在迭代<h:dataTable>时也仅是可用的<h:dataTable>,而不是在<h:dataTable>之前或之后。本质上,您试图访问bean的action方法中的组件的值,而<h:dataTable>组件没有迭代它,所以这些值总是返回null

为了以编程方式模拟<h:dataTable>迭代,以便收集所需的值,您需要通过UIComponent#visitTree()访问<h:dataTable>并收集VisitCallback实现中感兴趣的信息。

代码语言:javascript
复制
UIData table = (UIData) viewRoot.findComponent("form:rm");
table.visitTree(VisitContext.createVisitContext(FacesContext.getCurrentInstance()), new VisitCallback() {
    @Override
    public VisitResult visit(VisitContext context, UIComponent target) {
        if (target instanceof HtmlSelectBooleanCheckbox) {
            HtmlSelectBooleanCheckbox checkbox = (HtmlSelectBooleanCheckbox) target;
            System.out.println("id: " + checkbox.getId());
            System.out.println("value: " + checkbox.getValue());
            // Collect them in an arraylist orso.
        }

        return VisitResult.ACCEPT;
    }
});

,但是,,在解决具体问题方面,您完全走错了方向。您应该在与要验证的输入组件相关联的验证器中执行验证,而不是在action方法中。下面是如何解决特定的具体功能需求:只有在选中同一行的复选框时,才能将输入字段验证为required

代码语言:javascript
复制
<h:column>
    <h:selectBooleanCheckbox binding="#{checkbox}" ... />
</h:column>
<h:column>                                              
    <h:inputText ... required="#{checkbox.value}" />
</h:column>

就这样。另外的优点是,验证器在<h:dataTable>迭代时运行,所以您也不需要所有的visitTree()代码。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18573168

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档