【问题标题】:JSTL, composite, NamingContainer and prependIdJSTL、复合、NamingContainer 和 prependId
【发布时间】:2011-11-01 17:15:34
【问题描述】:

我编写了一个复合组件,想使用保留的 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

【问题讨论】:

  • 澄清一下,您想使用组件外部的ID,对吧?
  • 没错。编辑澄清。
  • 但要清楚一点,我在这里感兴趣的一点是 JSTL 代码对NamingContainerprependId 行为的影响。

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


【解决方案1】:

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

换句话说,JSTL 和 JSF 并不像您对编码所期望的那样同步运行。通常您希望使用 Facelets 的 &lt;ui:param&gt; 而不是 JSTL &lt;c:set&gt;

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

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

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

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

【讨论】:

  • 不太喜欢绑定有很多原因:需要在 Java 端维护一个 bean,每个组件上每个绑定的对象实例的多样性乘以用户,我的一些会话范围问题遇到过带有数据表绑定的 Seam+RichFaces。但这是另一场辩论。感谢 RichFaces JavaScript API,找到了另一种方法。这里是解决方案:$('#' + "#{rich:clientId(id)}".replace(/(:|\.)/g,'\\\$1')).mask("#{pattern}");。除此之外,我总是不明白为什么 JSTL 会阻止 prependId 行为。
猜你喜欢
  • 2012-01-17
  • 1970-01-01
  • 1970-01-01
  • 2016-02-19
  • 2014-02-18
  • 1970-01-01
  • 2012-05-13
  • 1970-01-01
  • 2012-02-24
相关资源
最近更新 更多