我正在尝试使用f:ajax
从复合组件事件更新父组件。
复合组件在这里:
<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>
现在使用此组件时如下:
<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>
我收到以下错误:
包含一个未知的id“模型” - 无法在组件make
的上下文中找到它答案 0 :(得分:15)
由于要更新的组件不在cc中,因此您必须以不同的方式解决它。首先给你的表单一个id:
<h:form id="myform">
然后从cc中解决目标组件:
render=":myform:model"
注意尾随冒号,它允许JSF从文档根目录中搜索属性。
答案 1 :(得分:4)
前一段时间我遇到同样的问题,仅仅是为了获取信息,我检查了jsf mojara实现的来源;这是它似乎如何工作: 类ajaxBehaviorRendered在遇到要渲染的 f:ajax 元素时,通过其方法getResolvedId分析 render 属性的内容:
private static String getResolvedId(UIComponent component, String id) {
UIComponent resolvedComponent = component.findComponent(id);
if (resolvedComponent == null) {
...
重点是方法findComponent:这个方法需要基础组件库作为在组件树中搜索的策略点。如果标识符以char“:”开头,则组件库是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);
}
此外,基本组件是当前组件最接近的NamingContainer类型的父级(即,您定义ajax组件的复合组件)。
//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();
}
}
然后,在这两种情况下,它都会从此开始使用给定的标识符搜索组件。
此行为是从jsf指定的行为。
从我的角度来看,如果你需要在复合材料之外引用一个组件,你必须定义完整的名称,使用前缀':'后跟'cc.clientId'属性。