我想知道在两个 ViewScoped bean 之间传递数据(对象)的最佳实践是什么。
由于出色解释的问题,它们需要在 View 范围内here (简而言之:在这两个 View 中,我都在 h:dataTable
中使用 h:commandLink
,这要求数据模型在提交时仍然存在)。
我现在的问题是点击链接也会导航到一个新 View ,所以使用下面的代码,我的对象被传递但是 DetailViewController
实例在那之后被杀死并创建一个新的当 View 改变时(如您所料)。
查看:
<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>
bean 类:
@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";
}
}
你会如何解决这个问题?我考虑过将对象放入 Flash 中:FacesContext.getExternalContext.getFlash()
...是否有更简单或更优雅的解决方案?
最佳答案
您可以使用 View 参数。 (参见 How do you pass view parameters when navigating from an action in JSF2?)
通常,您的方法返回带有查询参数的 url:
public String showDetail(Item i) {
return "view_detail.xhtml?id="+i.getId();
}
然后在您的 view_detail.xhtml 文件中,您添加一个 f:viewParam 标记评估您的 bean 字段:
<f:metadata>
<f:viewParam name="id" value="#{myBean.id}" />
</f:metadata>
然后从您的支持 bean,您使用该字段在您的 @postConstruct 方法中获取您的 Item 实例。 如果不使用f:viewparam标签,也可以通过fetch请求参数获取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");
}
}
}
关于jsf - 在两个 ViewScoped ManagedBean 之间传递对象的最佳解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21338185/