【问题标题】:How to use generated ids in EL (jsf, composite)?如何在 EL(jsf、composite)中使用生成的 id?
【发布时间】:2016-03-29 23:38:14
【问题描述】:

我想要一个合成器

<h:form id="f_imgA" >
        <h:graphicImage id="imgA"
            onclick="document.getElementById('#{k_imgA.clientId}').value=mods(event)"
            value="images/img?r=#{Math.random()}">
            <f:ajax event="click" listener="#{mBean.handleEvent}"
                execute="@this k_imgA" render="@this"></f:ajax>
        </h:graphicImage>
        <h:inputHidden id="k_imgA" binding="#{k_imgA}" value="#{mBean.keyX}" />
</h:form>

当我写作时

<comps:cimg imgId="imgA" />

此代码的最初目的是将修饰符状态(Ctrl、Shift、Alt)发送到服务器。

我有

<composite:interface>
    <composite:attribute name="imgId" />
</composite:interface>

<composite:implementation>
    <h:form id="f_#{cc.attrs.imgId}">
        <h:graphicImage id="#{cc.attrs.imgId}"
            onclick="document.getElementById('#{k_${cc.attrs.imgId}.clientId}').value=mods(event)"
            value="images/img?r=#{Math.random()}">
            <f:ajax event="click" execute="@this k_#{cc.attrs.imgId}"
                listener="#{mBean.handleEvent}" render="@this">
            </f:ajax>
        </h:graphicImage>
        <h:inputHidden id="k_#{cc.attrs.imgId}"
            binding="k_#{cc.attrs.imgId}" value="#{mBean.keyX}" />
    </h:form>
</composite:implementation>

这在意料之中是行不通的。有问题的表达是

#{k_${cc.attrs.imgId}.clientId}

它旨在返回 hiddenInput 的 clientId id 为 k_imgA 。据我所知,EL 无法处理上述嵌套表达式,但值得一试。那么有没有简单直接的方法来获取k_imgA的clientId呢?如果可以避免的话,我不想使用更多的 javascript。

编辑: 不要对#{Math.random()} 感到困惑,因为我有一个名为“Math”的bean。

javascript函数mods由

给出
<h:outputScript target="body">function mods(event) {return  ((event.ctrlKey)?1:0)+((event.shiftKey)?2:0)+((event.altKey)?4:0)} </h:outputScript>

【问题讨论】:

    标签: jsf-2 el composite-component


    【解决方案1】:

    你不需要摆弄那些_#{cc.attrs.imgId}。只需给组合一个固定的id。他们已经在自己命名容器了。然后 JSF 会担心剩下的事情。

    <composite:implementation>
        <h:form id="f">
            <h:graphicImage id="i" ... />
            <h:inputHidden id="k" ... />
        </h:form>
    </composite:implementation>
    

    用法:

    <comps:cimg id="imgA" />
    

    生成的 HTML:

    <form id="imgA:f" ...>
        <img id="imgA:f:i" ... />
        <input id="imgA:f:k" ... />
    </form>
    

    对于 JS 的尝试,你最好使用元素自己的 ID 作为基础:

    <h:graphicImage onclick="document.getElementById(id.substring(0,id.lastIndexOf(':')+1)+'k').value='...'" />
    

    或者,更简单,如果隐藏元素保证是生成的 HTML DOM 树中图像元素的直接兄弟,那么只需通过Node#nextSibling 抓取它:

    <h:graphicImage onclick="nextSibling.value='...'" />
    <h:inputHidden ... />
    

    binding 永远不会像在您尝试的构造中那样工作,即便如此,您最好通过请求范围内的 Map 或所谓的支持组件来实现。

    另见:

    【讨论】:

    • 我试过了(通过复制和粘贴),但结果是只有最后一个副本有效。但也许我在一般理解上遗漏了一些要点(哦,我很确定我在一般理解上遗漏了很多要点,但是其中有很多我无法弄清楚哪一个适用于此)。 “nextSibling”看起来是最有前途的方法,也不是通用方法。必须根据您的建议进行一些实验。这需要一些时间。
    • 不确定“最后一个副本”是什么意思。您只需要确保完全删除 binding,否则它们会相互覆盖直到最后一个,并且与所描述的症状相匹配。
    • 是的,这是一个绑定问题。我想多次使用复合材料(我为什么还要费心制作一个?)。这个想法来自stackoverflow.com/a/8656921/4142984,只要绑定键都不同,它就可以正常工作。只要组合不在 NamingContainer 内,您建议的带有 javascript 和子字符串的解决方案就可以工作。
    • 复合是容器本身的命名。这正是它起作用的原因,以及为什么您可以重复使用它们而不会在所有地方面临重复的组件 ID 错误。我也没有看到我的 JavaScript 示例是如何命名容器父依赖的。
    • 据我了解,这只是故事的一半。如果复合材料在其他容器内,clientIds 不会是 external:imgA:f:k 还是我有误解?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2013-08-23
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    • 1970-01-01
    相关资源
    最近更新 更多