【问题标题】:JSF Link not working (with Primefaces)JSF 链接不工作(使用 Primefaces)
【发布时间】:2012-04-26 22:49:48
【问题描述】:

抱歉,非常基本的问题...

我有一个显示在页面上的“留言板线程”列表。我希望能够单击其中一个并重定向到显示该线程详细信息的页面。尽管谷歌搜索了一段时间,但我仍在苦苦挣扎......

(顺便说一下,我正在使用 PrimeFaces)

这是我的“列表”页面中的相关代码:

<p:commandLink value="#{thread.title}" action="#{messageboardBean.showThread()}"> 
    <f:param name="threadId" value="#{thread.id}" />
</p:commandLink>

(在 h:form 元素中)

这是我命名 bean 的一部分(其他方法也可以)

...
    @ManagedProperty(value="#{param.threadId}")
    private Long threadId;
...
    public String showThread() {
        System.out.println("id is " + getThreadId());
        return "messageboard/list";
    }
...

你可以看到我的方法还没有实现,但它甚至没有被调用。谁能告诉我为什么?

顺便说一句,我也尝试了 h:link,同样(或相似)的问题。

谢谢!

更新 - 已解决

感谢以下帮助,这是我的解决方案(我已将“留言板”重命名为“讨论”)。

使用此代码生成链接

value:在页面上显示什么,在我的例子中是我讨论的标题 结果:指edit.xhtml,我想去的faces文件 ...并且 [request] 参数将被称为“threadId”,并且在我的“线程”对象中具有 id 属性的值。

在edit.xhtml页面,我有这个

<f:metadata>
    <f:viewParam name="threadId" value="#{viewDiscussionBean.threadId}" />
    <f:event type="preRenderView" listener="#{viewDiscussionBean.loadDiscussion}" />
</f:metadata>

注意'threadId'和第一页的param名字一样,绑定到我的viewDiscussionBean的threadId属性上。

然后,一旦在我的 bean 上设置了所有参数,我就会调用 viewDiscussionBean 的 loadDiscussion 方法。由于它现在具有 threadId 属性,因此它能够做到这一点(见下文)

我的 viewDiscussionBean 具有以下托管属性(我认为 viewParam 标签设置了这个,而不是相反)。

@ManagedProperty(value="#{param.threadId}")
private Long threadId; 

private Discussion thread;

所以一旦设置好了,这个方法就可以运行(因为它现在有一个 ID)

public String loadDiscussion() {
    thread = mbDao.find(threadId);
    return "edit";
}

这只是使用 DAO(使用 Hibernate)来查找具有该 ID 的讨论线程,并将其设置在 bean 中。然后……

在我的 edit.xhtml 页面中,我可以使用类似的方式访问讨论线程中的值

<h:outputText value="#{viewDiscussionBean.thread.message}" />

瞧!谢谢。

【问题讨论】:

    标签: java jsf-2 primefaces


    【解决方案1】:

    UICommand 操作未被调用的原因有很多。您可以在这里找到它们:commandButton/commandLink/ajax action/listener method not invoked or input value not updated 其中包括缺少表单、嵌套表单或表单其他地方的转换/验证错误、位于数据模型未正确保留的数据表中等等。

    对于您的特定功能要求,最好使用&lt;h:link&gt;。命令链接发出 POST 请求,在您的特定情况下,该请求不会以 URL 中带有线程 ID 的可书签 URL 结束。 &lt;h:link&gt; 创建一个完整的链接,该链接可添加书签和搜索机器人索引。

    例如

    <h:link value="#{thread.title}" outcome="messageboard/list"> 
        <f:param name="threadId" value="#{thread.id}" />
    </h:link>
    

    这不需要表单或操作方法。您只需要将 @ManagedProperty 移动到与 messageboard/list 关联的 bean,或者在允许更细粒度的验证/转换的 messageboard/list 视图中将其替换为 &lt;f:viewParam&gt;

    另见:

    【讨论】:

    • 感谢这些链接。当我开始工作时,会阅读并回帖。非常感谢!
    • 谢谢大家,使用你的提示让它工作了。我将更新我的问题以显示我完成的代码。
    【解决方案2】:

    您最好的选择可能是使用BalusCanswer 并使用&lt;h:link&gt;。不过,我对您看到的行为有一些想法。

    Primefaces &lt;p:commandLink&gt;(如 &lt;p:commandButton&gt;)默认使用 ajax。因此,从您的操作返回结果不会产生任何实际导航。这可能会使您的操作看起来没有被调用。尝试将ajax=false 添加到您的&lt;p:commandLink&gt;

    使用&lt;h:link&gt; 时,导航会在呈现链接时解决,而不是在单击时解决。修改你的例子:

    <h:link value="#{thread.title}" outcome="#{messageboardBean.showThread()}"> 
        <f:param name="threadId" value="#{thread.id}" />
    </h:link>
    

    showThread() 将在呈现包含链接的视图时被调用(我认为)。如果您没有在正确的时间进行检查,这也可能使它看起来像是正在调用该方法。

    在这两种情况下,这都不能解释为什么您根本看不到 System.out 的消息,但我知道我已经尝试过认为它是故障安全的,但仍然没有看到输出,这一切取决于您的容器、配置、启动方式等。

    【讨论】:

    • 感谢您的意见,布赖恩。当我回到家时,我将能够测试所有这些,并在稍后发布我的结果。
    猜你喜欢
    • 2013-06-12
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    • 2015-12-29
    • 2013-06-09
    • 1970-01-01
    • 2014-08-12
    • 2013-11-25
    相关资源
    最近更新 更多