添加第二个复合组件后,错误<f:ajax>包含未知ID </f:ajax>

时间:2015-02-19 14:06:26

标签: ajax jsf composite-component

我尝试在我的应用程序中使用复合组件。当我添加了第一个组件时它已经工作了,但是当我再次添加组件时,我遇到了错误:

  

&#34; javax.servlet.ServletException:包含一个未知的id&#39; j_idt202:kladrRegion-dctKladrRegion&#39; - 无法在组件searchButton&#34;

的上下文中找到它

这是实施代码:

<cc:interface>
    <!-- properties -->
    <cc:attribute name="isDisabled" type="java.lang.Boolean" /> 
    <cc:attribute name="freeForm" type="java.lang.String" /> 
    <cc:attribute name="houseNum" type="java.lang.String" />
    <cc:attribute name="korpusNum" type="java.lang.String" />
    <cc:attribute name="flatNum" type="java.lang.String" />

    <cc:attribute name="kladrRegion" type="java.lang.String" />
    <cc:attribute name="cbKladrRegion" type="javax.faces.component.html.HtmlSelectOneMenu" />
    <cc:attribute name="kladrRegions" type="java.util.List" />

    <cc:attribute name="kladrCity" type="java.lang.String" />
    <cc:attribute name="cbKladrCity" type="javax.faces.component.html.HtmlSelectOneMenu" />
    <cc:attribute name="kladrCities" type="java.util.List" />

    <cc:attribute name="kladrSearch" type="java.lang.String" />
    <cc:attribute name="cbKladrSearch" type="org.icefaces.ace.component.combobox.ComboBox" />
    <cc:attribute name="kladrSearches" type="java.util.List" />

    <!-- methods -->
    <cc:attribute name="listener" 
                  method-signature="void actionListener(javax.faces.event.AjaxBehaviorEvent)"/>
    <cc:attribute name="kladrRegionChange" 
                  method-signature="void actionListener(javax.faces.event.AjaxBehaviorEvent)"/>
    <cc:attribute name="kladrCityChange" 
                  method-signature="void actionListener(javax.faces.event.AjaxBehaviorEvent)"/>
    <cc:attribute name="kladrDlgCloseClick" 
                  method-signature="void actionListener(javax.faces.event.AjaxBehaviorEvent)"/>
    <cc:attribute name="kladrDlgSaveClick" 
                  method-signature="void actionListener(javax.faces.event.AjaxBehaviorEvent)"/>
    <cc:attribute name="searchKladrAction" 
                  method-signature="java.lang.String action(java.lang.String)"/>
</cc:interface>

<cc:implementation>
    <h:panelGrid styleClass="panelGrid" columns="2">
        <h:panelGroup styleClass="panelGroup">
            <div class="searchWrap">
                <h:commandLink id="searchButton"
                               disabled="#{cc.attrs.isDisabled}"
                               onclick="openKladrDialog(this, '#{cc.clientId}')">
                    <h:graphicImage value="/resources/images/search.png" 
                                    alt="#{usertag.labelSearchAddr}" />
                    <f:ajax event="click" 
                            render="kladrRegion-dctKladrRegion"
                            listener="#{cc.attrs.listener}"/>
                </h:commandLink>
            </div>
        </h:panelGroup>

        ...etc.

    </h:panelGrid>

    <!-- dialog -->
    <div id="#{cc.clientId}_kladrDialog">
        <h:panelGrid styleClass="panelGrid" columns="3">            
            <h:outputLabel value="Country" class="outputLabel" for="kladrCountry" />
            <h:panelGroup styleClass="panelGroup"> 
                <ice:inputText disabled="true" value="Russia" 
                               styleClass="ui-inputfield ui-corner-all inputText kladrSearchFormInput kladrSearchFormInputWidth" />    
                <h:inputHidden id="kladrCountry" value="179" />
            </h:panelGroup>
            <h:outputLabel />

            <h:outputLabel value="Region" class="outputLabel" />
            <h:selectOneMenu id="kladrRegion-dctKladrRegion" 
                             value="#{cc.attrs.kladrRegion}" >
                <f:selectItems value="#{cc.attrs.kladrRegions}" var="region" 
                               itemLabel="#{region.value}" itemValue="#{region.id}" />                                
                <f:ajax render="@this kladrCity-dctKladrCity" 
                        listener="#{cc.attrs.kladrRegionChange}" />
            </h:selectOneMenu>

            ... etc.
    </div>

</cc:implementation>

这是代码代码:

<kladr:usertag  isDisabled="#{PolicyBean.policyDisabled}"
                freeForm="#{PolicyBean.policyAuto.holder.baseAddress.freeForm}"
                houseNum="#{PolicyBean.policyAuto.holder.baseAddress.houseNum}"
                korpusNum="#{PolicyBean.policyAuto.holder.baseAddress.korpusNum}"
                flatNum="#{PolicyBean.policyAuto.holder.baseAddress.flatNum}"

                kladrRegion="#{PolicyBean.kladrRegion}"
                cbKladrRegion="#{PolicyBean.cbKladrRegion}"
                kladrRegions="#{PolicyBean.kladrRegions}"

                kladrCity="#{PolicyBean.kladrCity}"
                cbKladrCity="#{PolicyBean.cbKladrCity}"
                kladrCities="#{PolicyBean.kladrCities}"

                kladrSearch="#{PolicyBean.kladrSearch}"
                cbKladrSearch="#{PolicyBean.cbKladrSearch}"
                kladrSearches="#{PolicyBean.kladrSearches}"

                listener="#{PolicyBean.holderKladrDlgOpenClick}"
                kladrRegionChange="#{PolicyBean.kladrRegionChange}"
                kladrCityChange="#{PolicyBean.kladrCityChange}"
                kladrDlgCloseClick="#{PolicyBean.kladrDlgCloseClick}"
                kladrDlgSaveClick="#{PolicyBean.kladrDlgSaveClick}"
                searchKladrAction="#{PolicyBean.kladrSearchClick(PolicyBean.kladrSearch)}" />

任何想法?

1 个答案:

答案 0 :(得分:1)

问题是,您的<h:selectOneMenu id="kladrRegion-dctKladrRegion">位于另一个父组件中,而不是<h:commandLink id="searchButton" ...

如果您指定了正确的绝对组件ID(或在同一父级内移动对话框),它将正常工作。

有关如何查找正确的组件ID的信息,请参阅Find component by ID in JSF

该异常告诉您组件"kladrRegion-dctKladrRegion"中没有标识为<h:panelGroup>的组件,并且生成的标识为"j_idt202"

如果您正在使用PrimeFaces,则可以使用返回正确组件ID的EL函数component('id')。见http://www.primefaces.org/docs/guide/primefaces_user_guide_5_1.pdf,第11.2章。