客户端 - 强制 JSF 呈现自动生成的客户端 ID



我使用组件绑定和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 属性。

  1. 呈现自动生成的 id 标签有什么要求?
  2. 有没有办法让jsf自动渲染所有的cliendId-s?(如人脸配置条目)
  3. 有没有办法确保呈现单个元素的 clientId(不显式为其提供 id)?

更新

我用一个技巧找到了解决方法:

<span id="#{componentBindings.myInput.clientId}">
    <h:inputText binding="#{componentBindings.myInput}" value="#{myBean.myProperty}" />
</span>

尽管在这种情况下有更好的方法,例如按照建议使用名称,但如果它不是您希望使用 ajax 渲染的输入字段,它可能会很有用。例如,对于分面:

<!-- 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>

如果您查看组件树,您会发现分面没有嵌套在表单中,它是 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>

我可能不是第一个找到此解决方法的人,但我决定分享它,因为我在任何地方都找不到它

来自 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 属性或组件具有客户端行为持有者(读取:<f:ajax>子项)时,它才会呈现 HTML 元素的 id 属性。

因此,您确实需要自己指定它:

<h:inputText id="foo" ... />

否则,请更改您的 JS 代码,以便它按输入name而不是id选择输入。

相关内容

  • 没有找到相关文章

最新更新