我们在支持JSF 2.2 + PrimeFaces的应用程序中使用SPA方法。 这个基本思想最初在这里描述得非常好:
Refreshing dynamic content with AJAX in JSF using SPA approach
但是,正如我们所知,使用此SPA方法在使用 @ViewScoped bean时存在缺陷。
由于我们实际上总是停留在相同的JSF视图中,因此当我们用新的SPA内容替换面板组的内容时,@ ViewScoped bean不会从内存中删除。
我找到了一个解决方案,但我想知道它是否是正确的方法,和/或是否有任何遗漏。
基本上,在我们的NavigationService bean中,它保存了在SPA AJAX请求期间要呈现的页面的名称,我们总是执行以下代码:
private void clearViewScopedBeans() {
Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
for(Iterator<Map.Entry<String, Object>> it = viewMap.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<String, Object> entry = it.next();
it.remove();
}
}
这应该确保在呈现新的SPA片段之后,删除所有以前存在的@ViewScoped bean。
但是,我认为上面的代码只删除了View Scoped bean,但没有删除相关的View States。这是对的吗?
我找到了一个旧的博客条目,似乎做了一点逻辑: http://javaevangelist.blogspot.sg/2014/08/jsf-21-tip-of-day-clearing-viewscope.html
但我不知道它是否正确。
此外,如果我们想支持多个窗口标签,我们的NavigationService bean(包含当前的SPA代码段页面名称)也必须是@ViewScoped,这会带来一个小问题:
当运行上面的代码来删除所有现有的@ViewScoped bean时......我们必须排除NavigationService bean本身!否则我们最终会加载相同的页面,因为实例化了一个新的NavigationService实例,并使用默认的SPA页面名称而不是新的。“
所以,总而言之,我们的代码最终看起来像这样,我们保留了一个&#34;排除&#34; bean名称,我们不想在SPA页面刷新时删除(即包含SPA页面名称的NavigationService bean)
private void clearViewScopedBeans() {
Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
for(Iterator<Map.Entry<String, Object>> it = viewMap.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<String, Object> entry = it.next();
if(!exclusionViewScopedBeans.contains(entry.getKey())) {
logger.info("Removing an instance of a @ViewScoped bean -> " + entry.getKey());
it.remove();
}
}
}
现在问题...... 这是处理这类SPA情况的正确方法吗?我们在这里遗漏了什么吗?
非常感谢任何反馈......非常感谢!
答案 0 :(得分:0)
我认为,在SPA(单页面应用程序)中移除/清除ViewScopedBeans没有比你的Maikel更好的解决方案了:
private void clearViewScopedBeans() {
Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
for(Iterator<Map.Entry<String, Object>> it = viewMap.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<String, Object> entry = it.next();
it.remove();
}
}
我试过很多,但SPA不是“官方推荐”使用JSF的方式,即多页应用,所以SPA需要更多的摆弄。
或者,Maikel,你找到了或者你用其他方式吗?