JSF Composite component <f:ajax> contains an unknown id - cannot locate it in the context of the component

孤人 提交于 2019-12-08 17:11:27

问题


I'm trying to update a parent component from a composite component event using f:ajax.

The composite component is here:

<cc:interface>
    <cc:attribute name="update" />
    <cc:attribute name="customid" required="true"/>
    <cc:attribute name="val" required="true"/>
    <cc:attribute name="selectedvalue" required="true"/>
</cc:interface>
<cc:implementation>
    <h:panelGrid columns="2" style="font-size: 10px" >
        <p:selectOneMenu id="#{cc.attrs.customid} value="#{cc.attrs.selectedvalue}">
            <f:selectItems value="#{cc.attrs.val}"/>
            <f:ajax event="change" render="#{cc.attrs.update" />
        </p:selectOneMenu>
        <p:commandButton type="button" icon="ui-icon-plus" onclick="dlg.show();" />
    </h:panelGrid>
</cc:implementation>

Now when using this component as follows:

<h:form>
    <ez:combo customid="make" val="#{vehicleBean.makes}" selectedvalue="#vehicleBean.vehicle.make}" update="model"  />
    <p:selectOneMenu id="model" value="#{vehicleBean.vehicle.model}">
        <f:selectItems value="#{vehicleBean.models}" />
    </p:selectOneMenu>
</h:form>

I get the following error:

contains an unknown id 'model' - cannot locate it in the context of the component make


回答1:


Since the component to update is outside the cc you have to address it in a different way. First give your form an id:

<h:form id="myform">

Then address the target component from your cc like this:

render=":myform:model"

Notice the trailing colon which lets JSF search the attribute from the document root.




回答2:


I had the same problem a while ago, just for information, I checked the jsf mojara implementation's sources; here is how it seems to work: The class ajaxBehaviorRendered, when encounters a f:ajax element to render, analyses the content of the render attribute through its method getResolvedId:


private static String getResolvedId(UIComponent component, String id) {

        UIComponent resolvedComponent = component.findComponent(id);
        if (resolvedComponent == null) {
...

The point is the method findComponent: this one needs of base component base as a strat point for searching in the component tree. If the identifier begins with the char ":", the component base is the viewRoot.



    UIComponent base = this;
     if (expr.charAt(0) == sepChar) {
        // Absolute searches start at the root of the tree
        while (base.getParent() != null) {
            base = base.getParent();
         }
        expr = expr.substring(1);
    }

Else the base component is the current component's closest parent of type NamingContainer (that is, your composite component where you are defining your ajax component).



    //Treat remainder of the expression as relative
    else if (!(base instanceof NamingContainer)) {
        // Relative expressions start at the closest NamingContainer or root
        while (base.getParent() != null) {
            if (base instanceof NamingContainer) {
                break;
            }
            base = base.getParent();
        }
    }

Then, in both cases, it starts to search the component with the given identifier from this start.

This behaviour is the one specified from jsf.

From my point of you, if you need to reference a component outside the composite, you have to define the complete name, usind the prefix ':' followed by the 'cc.clientId' attribute.



来源:https://stackoverflow.com/questions/9858699/jsf-composite-component-fajax-contains-an-unknown-id-cannot-locate-it-in-th

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!