在两个ViewScoped Managed Bean之间传递对象的最佳解决方案

时间:2014-01-24 16:57:49

标签: jsf jsf-2

我想知道在两个ViewScoped bean之间传递数据(一个对象)的最佳实践是什么。

他们需要进行范围查看,因为问题很明确地解释here(简而言之:在两个视图中我都在h:commandLink内使用h:dataTable,这需要DetailViewController提交时数据模型仍然存在。

我现在的问题是单击链接也会导航到新视图,因此使用以下代码,我的对象会被传递,但<h:dataTable value="#{searchController.dataModel}" var="item"> ... <h:column> <f:facet name="header">Action</f:facet> <h:commandLink id="open" value="open" action="#{searchController.showDetail(item)}" /> </h:column> </h:dataTable> 实例在此之后被杀死,并且在视图中创建一个新实例变化(如你所料)。

查看:

@ManagedBean
@ViewScoped
public class SearchController {

    @ManagedProperty(value="#{detailViewController}")
    private DetailViewController detailViewController;

    // getters, setters, etc. ...

    public String showDetail(Item i) {
        detailViewController.setItem(i);
        return "view_detail.xhtml";
    }

}

豆:

FacesContext.getExternalContext.getFlash()

你会如何解决这个问题?我想过将对象放在Flash中:{{1}} ...是否有更简单或更优雅的解决方案?

1 个答案:

答案 0 :(得分:0)

您可以使用视图参数。 (见How do you pass view parameters when navigating from an action in JSF2?

通常,您的方法会返回带有查询参数的网址:

 public String showDetail(Item i) {
    return "view_detail.xhtml?id="+i.getId();
 }

在view_detail.xhtml文件中,添加一个f:viewParam标记,用于评估bean字段的on:

<f:metadata>
    <f:viewParam name="id" value="#{myBean.id}" />
</f:metadata>

然后从您的支持bean中,使用该字段在@postConstruct方法中获取Item实例。 如果不使用f:viewparam标记,还可以获取请求参数以获取id。

private String id;
private Item item;

@PostConstruct
public void init() {
  if (id != null) {
    item = fetchItem(id);
  } else {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    Map<String, String> requestParameterMap = externalContext.getRequestParameterMap();
    if (requestParameters.containsKey("id")) {
       id = requestParameters.get("id");
       item = fetchItem(id);
    } else {
       throw new WebServiceException("No item id in request parameters");
    }
  }
}
相关问题