Zee*_*mee 4 tree jsf naming-containers custom-component jsf-1.2
我尝试编写自己的树组件.树节点呈现为包含树组件的子组件的div,例如:
<my:tree id="extendedTree"
value="#{controller.rootNode}"
var="node">
<h:outputText id="xxx" value="#{node.name}" />
<h:commandLink value="Test" actionListener="#{controller.nodeSelectionActionListener}" />
</my:tree>
Run Code Online (Sandbox Code Playgroud)
到目前为止,这么好 - 一切都按预期工作,但h:outputText重复获得相同的id.
所以我有我的组件工具javax.faces.NamingController,覆盖getContainerClientId():
@Override
public String getContainerClientId(FacesContext context) {
String clientId = super.getClientId(context);
String containerClientId = clientId + ":" + index;
return containerClientId;
}
Run Code Online (Sandbox Code Playgroud)
index在迭代过程中设置和更新节点.但getContainerClientId()每个孩子只会被召唤一次(不是每次迭代和每个孩子,正如我所期望的那样).这会导致每个子ID都以相同的容器ID作为前缀:
form:treeid:0:xxx
Run Code Online (Sandbox Code Playgroud)
覆盖也是一样的getClientId().
我错过了什么?
答案隐藏在JSF 1.2规范 3.1.6章的底部:
3.1.6客户端标识符
...
除非
setId()被调用,否则此方法返回的值在组件实例的整个生命周期内必须相同,在这种情况下,下次调用时将重新计算该值getClientId().
换句话说,结果getClientId()默认是由JSF组件缓存的UIComponentBase#getClientId()(在Mojarra 1.2_15中也见于第275行的nullcheck),并在UIComponentBase#setId()调用时重置此缓存(另请参阅第358行)在Mojarra 1.2_15).只要您不重置缓存的客户端ID,它将在每次getClientId()调用时返回相同的值.
因此,在渲染子encodeChildren()组件时,在实现组件或渲染器时,最可能看起来像这样,
for (UIComponent child : getChildren()) {
child.encodeAll(context);
}
Run Code Online (Sandbox Code Playgroud)
你应该为每个孩子调用UIComponent#setId()结果,UIComponent#getId()在编码子进程之前重置内部缓存的客户端ID:
for (UIComponent child : getChildren()) {
child.setId(child.getId());
child.encodeAll(context);
}
Run Code Online (Sandbox Code Playgroud)
在UIData后面的类<h:dataTable>实现这是否顺便也(见行1382,因为它是在钻嘴鱼科1.2_15).请注意,这不是JSF 1.x特定的,同样适用于JSF 2.x(以及UIRepeatFacelets背后的类<ui:repeat>).