JSTL,复合,NamingContainer和prependId

时间:2011-08-23 07:18:51

标签: jsf-2 jstl composite-component naming-containers

我编写了一个复合组件,并希望使用保留的EL #{component.clientId}来生成JQuery绑定。要在页面中的另一个位置(组件外部)中使用此检索到的clientId,我使用JSTL将其存储在视图范围变量中。奇怪的是,JSTL似乎阻止了在其子代前面附加id的自然复合组件行为(NamingContainer行为)。我知道JSTL有点棘手,干扰其他组件(例如ui:repeat)因为生命周期的事情,但在这里我不明白这种行为。

一些具体的代码比这个长篇演讲更好:

<html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:rich="http://richfaces.org/rich"
        xmlns:c="http://java.sun.com/jsp/jstl/core"    
        xmlns:composite="http://java.sun.com/jsf/composite">
    <composite:interface>
        […]
    </composite:interface>
    <composite:implementation>
        <rich:dataTable id="mySoLovedDataTable" […]>
            #{component.clientId}
            <!-- Commenting or uncommenting this line make the whole point -->
            <c:set var="targetClientId" value="#{component.clientId}" scope="view" />
            […]
        </rich:dataTable>
    </composite:implementation>
</html>

在评论的行中,#{component.clientId}提供类似j_idt261:mySoLovedDataTable的内容。

如果该行已注释掉,则只会显示mySoLovedDataTable

1 个答案:

答案 0 :(得分:3)

JSTL在视图构建期间运行。它运行的时候JSF将视图模板解析为一个完整且可渲染的JSF组件树。 JSF在视图渲染时运行。它运行的时候JSF将组件树编码成一堆HTML。您可以按如下方式对其进行可视化:JSTL首先从上到下运行,并仅使用JSF标记生成结果。然后,在JSF渲染响应阶段,JSF将从上到下运行并生成HTML结果。

换句话说,JSTL和JSF并不像编码所期望的那样同步运行。通常,您希望使用Facelets的<ui:param>代替JSTL <c:set>

<ui:param name="targetClientId" value="#{component.clientId}" />

请注意,这并未在任何范围内设置任何内容。它只是为给定的表达式创建了一种“别名”。我不确定它是否按照您的意图在您的特定情况下工作,但据我了解功能要求,您希望能够在视图中进一步获取客户端ID <rich:dataTable>,< em>在组件之后。在这种情况下,最好使用binding

<rich:dataTable binding="#{table}" ...>
    ...
</rich:dataTable>

<script>
    var $table = jQuery("[id='#{table.clientId}']");
    // ...
</script>