简体   繁体   English

JSTL,复合,NamingContainer和prependId

[英]JSTL, composite, NamingContainer and prependId

I have written a composite component and want to use the reserved EL #{component.clientId} to make a JQuery bind. 我已经编写了一个复合组件,并想使用保留的EL #{component.clientId}进行JQuery绑定。 To use this retrieved clientId in a another place in the page (outside the component), I use JSTL to store it in a view scope variable. 要在页面的另一个位置(组件外部)使用此检索到的clientId,我使用JSTL将其存储在视图范围变量中。 The strange thing is that JSTL seems to prevent the natural composite component behavior of appending its id in front of its children ( NamingContainer behavior). 奇怪的是,JSTL似乎阻止了将其id附加在其子代之前的自然复合组件行为( NamingContainer行为)。 I know that JSTL is a little tricky, interfering with other components ( ui:repeat for instance) because of lifecycle things, but here I don't understand this behavior. 我知道JSTL有点棘手,由于生命周期的原因,它会干扰其他组件(例如ui:repeat ),但是在这里我不了解这种行为。

Some concrete code is better than this long speech: 一些具体的代码比这个冗长的演讲更好:

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

With the line commented on, #{component.clientId} gives something like j_idt261:mySoLovedDataTable . 注释掉该行后, #{component.clientId}给出类似于j_idt261:mySoLovedDataTable

With the line commented out, it gives just mySoLovedDataTable . 注释掉该行后,仅给出mySoLovedDataTable

JSTL runs during view build time. JSTL在视图构建期间运行。 It runs at the point that JSF parses the view template into a fullworthy and renderable JSF component tree. 它在JSF将视图模板解析成一个完全有价值且可渲染的JSF组件树时运行。 JSF runs during view render time. JSF在视图渲染期间运行。 It runs at the point that JSF encodes the component tree into a bunch of HTML. 它在JSF将组件树编码为一堆HTML的点上运行。 You can visualize it as follows: JSTL runs from top to bottom first and produces a result with JSF tags only. 您可以将其可视化如下:JSTL从上到下先运行,并且仅使用JSF标记产生结果。 Then, during JSF render response phase, JSF will run from top to bottom and produce HTML result. 然后,在JSF渲染响应阶段,JSF将自上而下运行并产生HTML结果。

In other words JSTL and JSF doesn't run in sync as you'd expect from the coding. 换句话说,JSTL和JSF不会像您期望的那样同步运行。 Usually you would like to use Facelets' <ui:param> instead of JSTL <c:set> . 通常,您想使用Facelets的<ui:param>而不是JSTL <c:set>

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

Note that this does not really set anything in any scope. 请注意,这实际上并没有在任何范围内设置任何内容。 It merely creates kind of an "alias" for the given expression. 它只是为给定的表达式创建一种“别名”。 I'm not sure if it works in your particular case the way as you intend, but as far I understand the functional requirement, you'd like to be able to obtain the client ID <rich:dataTable> further in the view, after the component. 我不确定它是否可以按您希望的方式在您的特定情况下工作,但是据我了解的功能要求,您希望能够在视图中进一步获取客户端ID <rich:dataTable>之后组件。 In that case, better use binding : 在这种情况下,最好使用binding

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM