奇怪的jsf ui:包括行为

时间:2012-06-11 14:43:06

标签: jsf xhtml facelets

这是一个真正的头脑刮板...我有一些命令链接,它们被设计为按钮,所以为了便于维护,我写了一个小的html片段,我可以包含一些参数来呈现风格很好的命令链接。

现在这很有效,除非动作结果是改变视图,此时,“包含”版本坚决拒绝服从点击导航,我不明白为什么!如果操作导致验证错误,则会显示错误,因此肯定会调用操作 - 并且我的日志会确认这一点,但是,如果没有验证错误,原始版本(不使用include)将导航到下一个页面很好,但使用包含的版本将无法导航。我尝试使用一个非常简单的“hello.xhtml”页面作为第二页,所以我知道它与新视图的内容无关。

为清晰起见编辑:我在页面上使用了几个按钮,其中大多数只是修改当前页面的状态,这些按钮都正常工作。只有当结果是改变观点时,“包含”版本才会出错。

我在Portal Server 6.1 / WAS 7.0上运行JSF 1.2

我花了太长时间试图解决这个问题,以便你们看看你是否有任何想法......

更新:为了节省涉及评论的问题,答案是我在导航规则中使用了from-action,它只匹配commandLink中使用的字符串 - 因此导航处理程序看到了{ {1}}作为from-action而不是#{bean[action]}

一些代码。

我的按钮模板:

#{applicationPage.doContinue}

在页面上使用的示例:

<ui:composition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xml:lang="en" lang="en">

    <ui:remove>
        Functional Button with arrow icon.
        Parameters:
        linkId           = The id for the commandLink.
        linkText         = The text to display on the button.
        linkTitle        = title text to display
        bean             = The bean name containing the action handler.
        action           = The action handler to call.
    </ui:remove>
    <div class="btn functionalButton">
        <h:commandLink id="#{linkId}" action="#{bean[action]}" title="#{linkTitle}" styleClass="functional">
                #{linkText}
                <span class="arrow icon" />
            <span class="tl" />
            <span class="tr" />
            <span class="bl" />
            <span class="br" />
        </h:commandLink>
    </div> 

</ui:composition>

此版本不会更改视图。

在使用include之前,代码看起来像这样(它应该解析并渲染到完全相同的html),然而这个版本更改视图就好了。

<ui:include src="/WEB-INF/facelets/content/functionalButton.xhtml">
    <ui:param name="linkId" value="applicationSubmit" />
    <ui:param name="bean" value="#{applicationPage}" />
    <ui:param name="action" value="doContinue" />
    <ui:param name="linkText" value="#{msg['button_FF060_continue']} " />
</ui:include>

1 个答案:

答案 0 :(得分:1)

更新:当与该操作相关联的<from-action>中的<navigation-case>仍然引用原始EL表达式时,可能会发生这种情况:

<from-action>#{applicationPage.doContinue}</from-action>

它不是被解释为实际的方法表达式,而是被解释为字符串文字,正好是您在action属性中定义的字符串文字。因此,当使用include / tag文件时,您应该将其更改为action属性中使用的文字EL表达式:

<from-action>#{bean[action]}</from-action>

或者更好,只需删除即可。如果您没有多个操作可能会返回相同的结果但需要不同的目标,则无效。我还建议只使用不带扩展名的<to-view-id>作为结果值。这样可以简化未来向JSF 2.0的迁移,因为这已经隐含了。




以下原始答案留待将来参考

我不确定,但可能Facelets 1.x根本不吃那个。这适用于Facelets 2.x.我从经验中无法分辨,因为我从未(ab)以这种方式使用过包含文件。

我建议您将其用作标记文件。另外一个好处是,这也会以更清晰的语法结束,并且可以在IDE自动完成中提供属性名称和描述。您需要做的就是创建/META-INF/my.taglib.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE facelet-taglib PUBLIC
    "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
    "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">

<facelet-taglib>
    <namespace>http://example.com/jsf/facelets</namespace>
    <tag>
        <tag-name>functionalButton</tag-name>
        <source>/WEB-INF/facelets/content/functionalButton.xhtml</source>
    </tag>
</facelet-taglib>

(属性的定义是可选的,如果需要,可以在<attribute>中添加为<tag>,我还建议将这些文件放在某个/tags子文件夹中,例如{ {1}})

如果您在/WEB-INF/facelets/tags注册时如下

/WEB-INF/web.xml

然后您将能够按如下方式使用它:

<context-param>
    <param-name>facelets.LIBRARIES</param-name>
    <param-value>/META-INF/my.taglib.xml</param-value>
</context-param>