【问题标题】:Replacing a managed bean instance from the backing bean从支持 bean 替换托管 bean 实例
【发布时间】:2012-06-03 14:15:43
【问题描述】:

做一个 CRUD,我有一个 RequestScoped Ticket bean。

我有一个 XHTML 页面,直到现在我一直在使用它来创建新票证;工单字段直接填充(#{ticket.description} 等)

现在我有一个列出票证的搜索表单,每张票证都有一个链接,其中票证 ID 作为参数。我希望支持 bean 从 EJB/JPA 中检索票证 bean(已经完成)并将其放入请求中。我看到了 3 种方法:

  • 将从 JPA 检索到的 bean 中的数据复制到注入提供的 bean 中。丑陋/容易遗漏。
  • 使用ExternalContex#getRequestMap 并自己将bean 放在那里。看起来不太妥当。我说的对吗?
  • 将我的票 bean 包含到另一个 bean 类中,这样我就可以做myNewBean.setTicket(ticketFromJpa);。似乎是最好的选择,但我不喜欢为此在页面中添加所有 EL 前缀。

有没有更清洁、更合适的方式来做我想做的事?

提前致谢。

更新: 用更多信息来改写我想要的内容。我在页面P1 中有一个commandLink,它在支持bean B1 中调用动作AB1 执行其逻辑并重定向到页面 P2。 我想在A 中设置一个(请求范围的)bean B2,并且B2 可用于绘制P2

通过实验,我发现在离开操作A 后,框架会创建一个新的B2 请求范围bean,所以看起来请求范围比我预期的要短。

Damian 提出的 flash 范围看起来更像我想要的,但迫使我围绕 #{flash} 重新设计页面,并且(当我想使用它来创建新 bean 时)我还必须添加bean 到 flash 中的操作方法(目前它只是转到页面并且托管 bean 可用)

我希望从那时起维护一个请求范围的 bean

【问题讨论】:

  • 为什么需要在请求中放入ticket?接下来你想做什么?
  • 我想将工单传递给 .xhtml 页面,以便它呈现工单数据。

标签: jsf-2 cdi


【解决方案1】:

要在另一个页面中查看票证,您可以执行以下操作之一:
1) 使用 h:link 和包含票证 ID 的 f:param

<h:link value="#{ticket.description}" outcome="/viewTicket" >
    <f:param name="id" value="#{ticket.id}" /
</h:link>

然后在 viewTicket.xhtml(或您所称的页面)中读取 ID 参数,并从 JPA 获取票证。

托管的基本上是这样的:

@ManagedBean
@ViewScoped
public class ViewTicketMBean implements Serializable {

    private String ticketId;
    private Ticket ticket;

    @PostConstruct
    public void init() {
        ticketId = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id");
        // read ticket from JPA by ID
    }

}

2) 如果您不想公开票证 ID,则可以使用 commandLink 代替 h:link,它在导航到 viewTicket.xhtml 之前,从 JPA 获取票证并将其放入 flash 范围内。然后,在 viewTicket 中,您可以从 flash 范围中获取票证。这就是 commandLink 的 action 方法的样子

Ticket ticket = null;
// get ticket from JPA    
FacesContext.getCurrentInstance().getExternalContext().getFlash().put("ticket", ticket);
return "/viewTicket";

【讨论】:

  • 您能否详细说明第一个选项?我对 JSF 很陌生,到目前为止,当我在 xhtml 中时,我只是在托管 bean 中呈现数据(在支持 bean 操作中更新)。我如何从 xhtml 本身调用 JPA?
  • 我现在要下班了,我稍后会检查第二个选项并告诉它进展如何。
  • 我更新了答案。您在托管 bean 的 @PostConstruct 方法中读取参数并从 JPA 获取票证。我建议你多学习一点 JSF,阅读一些教程,阅读文档等。这是非常基础的。
  • flash方法更像我需要的,但是我觉得有点麻烦(强制我在每个重定向到页面的动作中都将bean添加到flash中,并通过flash in进行引用艾尔)。你知道有没有办法解决这些问题?
  • 您可以使用以下行从 @PostConstruct 中的 flash 中读取 bean,而不是在 EL 中引用 Flash:FacesContext.getCurrentInstance().getExternalContext().getFlash().get("ticket") ;我认为没有其他方法可以实现这一点。通常使用 h:link。
猜你喜欢
  • 2012-01-17
  • 2012-02-06
  • 2011-11-23
  • 2011-06-10
  • 1970-01-01
  • 2015-05-06
  • 2012-11-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多