【问题标题】:Concatenating strings within EL expression defined in an attribute of a facelets tag在 facelets 标记的属性中定义的 EL 表达式中连接字符串
【发布时间】:2011-11-15 05:08:06
【问题描述】:

我需要为一个属性写一个 EL 表达式,如下所示:

#{cc.attrs.appreciatedByCurrentUser ? (cc.attrs.count +'<br/>'+ (cc.attrs.count-1)) : ((cc.attrs.count+1) +'<br/>'+ cc.attrs.count)}

现在的问题是这会产生错误,因为字符串无法连接,我正在这样做。那么我该如何纠正呢?

我正在使用带有 facelets 的 JSF 2.0。


编辑:

我正在使用以下内联 javascript 解决问题

            <script type="text/javascript">
                var count=#{cc.attrs.count};
                document.write(#{cc.attrs.appreciatedByCurrentUser} ? (count-1) +'<br/>'+count  : count+'<br/>'+ (count+1));
            </script>

你能想到这有什么问题吗?

【问题讨论】:

    标签: jsf jsf-2 facelets el


    【解决方案1】:

    EL 中的字符串连接只能通过在表达式中内联来实现。 + 运算符在 EL 中仅是求和运算符。此外,&lt;&gt; 是 XML 属性中的无效字符,因此您必须将它们转义(并指示 &lt;h:outputText&gt; 不要再通过 escape="false" 转义它们):

    <h:outputText value="#{cc.attrs.count}&lt;br/&gt;#{cc.attrs.count-1}" escape="false" rendered="#{cc.attrs.appreciatedByCurrentUser}" />
    <h:outputText value="#{cc.attrs.count+1}&lt;br/&gt;#{cc.attrs.count}" escape="false" rendered="#{!cc.attrs.appreciatedByCurrentUser}" />
    

    或者,您也可以使用&lt;c:set&gt; 为表达式设置别名:

    <c:set var="appreciated" value="#{cc.attrs.count}&lt;br/&gt;#{cc.attrs.count-1}" />
    <c:set var="notAppreciated" value="#{cc.attrs.count+1}&lt;br/&gt;#{cc.attrs.count}" />
    <h:outputText value="#{cc.attrs.appreciatedByCurrentUser ? appreciated : notAppreciated}" escape="false" />
    

    【讨论】:

    • 我有这个想法,但我在你的另一个回答中看到你谈到了与rendered 属性相关的性能问题(每个rendered 1 毫秒)如果我使用您提出的解决方案将在我的页面中添加 atleast 50 多个渲染属性。因此延迟 50 毫秒..!??
    • 对于真正可以忽略不计的纯输出组件。无论如何,我使用ui:param 添加了一个替代方案。使用您的 JavaScript 方法,您只需将 CPU 时间从服务器端转移到客户端。
    • 是的,javascript 方法在性能方面没有好处,但我只是想知道(在 JavaScript 方向上思考一下),这种内联 javascript 使用是否有任何危害。尽管我喜欢你的解决方案使用ui:param
    • 使用 ui:param 可以使用连接字符串作为资源包的键。无论如何,美国人不是把EL发音为ILL吗?我不认为这是一个意外;)
    • 我喜欢ui:param 的建议。直到现在我才需要那个元素。
    【解决方案2】:

    可以使用java.lang.String.concat(String) 方法在EL 中连接字符串。因此您的代码可能如下所示:

    <h:outputText value="#{cc.attrs.appreciatedByCurrentUser ?  (''.concat(cc.attrs.count).concat('&lt;br/&gt;').concat(cc.attrs.count-1)) :  (''.concat((cc.attrs.count+1)).concat('&lt;br/&gt;').concat(cc.attrs.count))}" escape="false" />
    

    但是,在这种特殊情况下,我会选择 BalusC 先生建议的选项之一,因为上面的代码看起来不太优雅。不过,在某些情况下,了解这种技术可能会很有用。

    我几乎不建议在这里使用 javascript 作为解决方法。

    【讨论】:

    • 请注意,这需要 EL 2.2。
    • @Fritz:EL 不是 JSF 的一部分。它是服务器的一部分。您甚至可以在 EL 2.2 上使用 JSF 1.x。
    • 我明白了,@BalusC 如何检查某个服务器是否使用了哪个 EL?我正在使用 Websphere 8.5、Java EE 6
    【解决方案3】:

    这是我唯一能想到的。

    <h:panelGroup rendered="#{cc.attrs.appreciatedByCurrentUser}">
       <h:outputText value="#{(cc.attrs.count)}" style="display:block;" />
       <h:outputText value="#{(cc.attrs.count-1)}" />
    </h:panelGroup>
    <h:panelGroup rendered="#{not cc.attrs.appreciatedByCurrentUser}">
       <h:outputText value="#{(cc.attrs.count+1)}" style="display:block;" />
       <h:outputText value="#{(cc.attrs.count)}" />
    </h:panelGroup>
    

    &lt;br&gt; 放在值属性中总是会在JSF 中引发错误,因此您必须使用display:block

    【讨论】:

    • 或者你可以添加xmlns="http://www.w3.org/1999/xhtml"并写&lt;h:outputText /&gt;&lt;br /&gt;&lt;h:outputText /&gt;
    猜你喜欢
    • 2012-10-08
    • 2015-07-10
    • 2013-06-10
    • 2015-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多