我想知道在两个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}} ...是否有更简单或更优雅的解决方案?
答案 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");
}
}
}