【问题标题】:Understanding ui:repeat client id and component finding理解 ui:repeat client id 和组件查找
【发布时间】:2015-11-20 02:06:49
【问题描述】:

莫哈拉 2.1。

问题实际上是关于组件查找算法的。

我有以下UIRepeat

<h:form id="frm">

    <ui:repeat id="repeater" value="#{bean.values}" var="v">
        <h:panelGroup id="pg">
            <!-- content -->
            <h:selectBooleanCheckbox id="cb" value="#{bean.v}">
                <f:ajax event="change" listener="#{bean.listener()}" render=":frm:repeater:pg" />
           </h:selectBooleanCheckbox>
           <!-- another content -->
        </h:panelGroup>
    </ui:repeat>

</h:form>

现在考虑AjaxBehaviorRenderer#getResolvedId的方法:

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

        UIComponent resolvedComponent = component.findComponent(id);
        if (resolvedComponent == null) {
            // RELEASE_PENDING  i18n
            throw new FacesException(
                "<f:ajax> contains an unknown id '"
                + id
                + "' - cannot locate it in the context of the component "+component.getId());
        }

        return resolvedComponent.getClientId();
    }

此方法旨在将渲染属性值解析为组件。现在,在调试器中,我发现在我的情况下使用以下参数调用该方法:

component = the instance of the HtmlSelectBooleanCheckbox
id = :frm:repeater:pg

现在,component.findComponent(id) 方法返回具有clientId - frm:repeater:0:pg 的组件。但是以component.findComponent(":frm:repeater:0:pg") 调用该方法会返回null

为什么?我预计结果会是一样的。我错过了什么?

【问题讨论】:

    标签: jsf jsf-2 mojarra


    【解决方案1】:

    这是根据 Mojarra 2.2.5 中的 impl issue 2958“fixed”,他们只是完全删除了该 nullcheck,而不是通过剥离迭代索引来改进它。从那时起,人们可以指定任意客户端 ID 而不会触发异常。我创建了API issue 1372 并提出了解决此问题的解决方案。

    因此,这意味着,从 Mojarra 2.2.5 开始,您可以对特定的 &lt;ui:repeat&gt;&lt;h:dataTable&gt; 迭代轮进行 ajax 更新,前提是模型得到正确保留(即它是视图范围的)。

    <h:form id="form">
        <ui:repeat id="list" value="#{['one','two','three']}" var="item">
            <h:outputText id="item" value="#{item}" /><br/>
        </ui:repeat>
    
        <h:commandButton value="Update second item">
            <f:ajax render=":form:list:1:item" />
        </h:commandButton>
    </h:form>
    

    但这也意味着,从 Mojarra 2.2.5 开始,您将永远不会面对众所周知的 " 包含未知 id 'foo' 无法在组件 'bar' 的上下文中找到它" 错误,这对初学者来说是令人困惑和不利的。

    另见:


    与具体问题无关,在您的具体情况下,您也可以只使用render="pg" 而不是render=":frm:repeater:pg",因为渲染目标组件与相同的命名容器父组件执行源组件。

    【讨论】:

    • 那么,在 Mojarra 2.2.5 之前,component.findComponent(:frm:repeater:pg) 返回一个与特定迭代项相关的组件,该组件由component 本身确定,对吧?
    • 这与 Mojarra 版本无关。错误的异常只发生在 2.2.5 之前。
    • 啊,现在我明白了,谢谢。在 Mojarra 2.2.12 中,我们只是先检查指定的 id 是否为“全局 id”。如果是这样,我们返回id.substring(1)。如果没有,那么只需返回 id。我认为它是按照您在评论中指出的那样实现的我们也可以改进 findComponent() 规范和算法以覆盖迭代索引。
    猜你喜欢
    • 2011-05-26
    • 1970-01-01
    • 2013-03-19
    • 2012-03-26
    • 2020-05-13
    • 2017-09-08
    相关资源
    最近更新 更多