1

这是一个真正令人头疼的问题...我有许多命令链接,它们的样式被设置为按钮,因此为了便于维护,我编写了一个小 html 片段,我可以包含一些参数来呈现一个样式精美的命令关联。

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

为清楚起见进行了编辑:我在页面上使用了几个按钮,其中大部分只是修改当前页面的状态,这些都可以正常工作。只有当结果是改变视图时,“包含”版本才会出现问题。

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

我花了太长时间试图解决这个问题,所以给你们看看你有没有什么想法......

更新:为了节省浏览评论的麻烦,答案是我在导航规则中使用了 from-action,它与 commandLink 中使用的字符串匹配 - 所以导航处理程序被 #{bean[action]}视为 from-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>

以及在页面上使用的示例:

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

此版本不会改变视图。

在使用包含之前,代码看起来像这样(应该解析并呈现为完全相同的 html),但是这个版本改变了视图就好了。

<div class="btn functionalButton">
    <h:commandLink id="applicationSubmit" styleClass="functional" action="#{applicationPage.doContinue}" title="#{msg['button_FF060_continue']}">
     #{msg['button_FF060_continue']} 
        <span class="arrow icon" id="arrow_continue" />
        <span class="tl" />
        <span class="tr" />
        <span class="bl" />
        <span class="br" />
    </h:commandLink>
</div>
4

1 回答 1

1

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

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

它没有被解释为实际的方法表达式,而是作为字符串文字,正是您在action属性中定义的那个。因此,当使用包含/标记文件时,您应该将其更改为在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>inside <tag>,我还建议将这些文件放在某个/tags子文件夹中,例如/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>

然后你就可以按如下方式使用它:

xmlns:my="http://example.com/jsf/facelets"
...
<my:functionalButton linkId="applicationSubmit" bean="#{applicationPage}" 
    action="doContinue" linkText="#{msg['button_FF060_continue']} " />
于 2012-06-11T14:59:59.363 回答