我使用组件绑定和clientId属性来查找我的javascript代码中的组件,如下所示:
<div data-for="@parent" data-example="#{componentBindings.myInput.clientId}" />
...
<h:inputText binding="#{componentBindings.myInput}" value="#{myBean.myProperty}" />
唯一的问题是,jsf有时候不会渲染inputText字段的id属性,所以即使我知道js代码中的clientId,我也找不到该元素,因为它在客户端上没有id属性侧。
更新
我找到了使用技巧的方法:
<span id="#{componentBindings.myInput.clientId}">
<h:inputText binding="#{componentBindings.myInput}" value="#{myBean.myProperty}" />
</span>
虽然在这种情况下有更好的方法,比如使用建议的名称,如果它不是你想用ajax渲染的输入字段,它可能是有用的。例如,使用facets:
<!-- myComponent.xhtml -->
<!-- ... -->
<cc:interface>
<cc:facet name="someFacet" required="true" />
</cc:interface>
<cc:implementation>
<h:form>
<cc:renderFacet name="someFacet"/>
</h:form>
</cc:implementation>
<!-- page.xhtml -->
<!-- ... -->
<my:myComponent>
<f:facet name="someFacet">
<h:inputText />
<!-- ... -->
</f:facet>
</my:myComponent>
如果你看一下组件树,你会看到,facet没有嵌套在表单中,它是cc的直接子元素。所以用ajax执行cc会很好:
<!-- myComponent.xhtml -->
<!-- ... -->
<cc:interface>
<cc:facet name="someFacet" required="true" />
</cc:interface>
<cc:implementation>
<h:form>
<cc:renderFacet name="someFacet"/>
<h:commandLink>
<f:ajax execute=":#{cc.clientId}" render=":#{cc.clientId}" />
</h:commandLink>
</h:form>
</cc:implementation>
但这会抛出格式错误的xml异常,因为客户端没有请求id的元素。有了这个技巧,你可以使它工作:
<cc:interface>
<cc:facet name="someFacet" required="true" preferred="true"/>
</cc:interface>
<cc:implementation>
<span id=#{cc.clientId}>
<h:form>
<cc:renderFacet name="someFacet"/>
<h:commandLink>
<f:ajax execute=":#{cc.clientId}" render=":#{cc.clientId}" />
</h:commandLink>
</h:form>
</span>
</cc:implementation>
我可能不是第一个发现这种解决方法的人,但我决定分享它,因为我没有找到它
答案 0 :(得分:1)
来自Mojarra的HtmlBasicRenderer
源代码(从2.1.17中的第672行开始):
/**
* @param component the component of interest
*
* @return true if this renderer should render an id attribute.
*/
protected boolean shouldWriteIdAttribute(UIComponent component) {
// By default we only write the id attribute if:
//
// - We have a non-auto-generated id, or...
// - We have client behaviors.
//
// We assume that if client behaviors are present, they
// may need access to the id (AjaxBehavior certainly does).
String id;
return (null != (id = component.getId()) &&
(!id.startsWith(UIViewRoot.UNIQUE_ID_PREFIX) ||
((component instanceof ClientBehaviorHolder) &&
!((ClientBehaviorHolder)component).getClientBehaviors().isEmpty())));
}
因此,如果组件具有id
属性集,或者组件具有客户端行为持有者(读取:id
个孩子),它只会呈现HTML元素的<f:ajax>
属性。
所以,你真的需要自己指定:
<h:inputText id="foo" ... />
否则,请更改您的JS代码,以便按name
而不是id
选择输入。