在SPA JSF 2.2应用程序中删除@ViewScoped bean



我们在启用JSF 2.2 + PrimeFaces的应用程序中使用了SPA方法。基本思想最初在这里描述得很好:

使用SPA方法在JSF中使用AJAX刷新动态内容

但是,正如我们所知,当使用@ViewScoped bean时,使用这种SPA方法有一个缺点。

因为我们实际上总是停留在同一个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页面名,而不是新的。

所以,总而言之,我们的代码最终看起来像这样,我们保留了一个"排除"bean名称的Map,我们不想在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情况的正确方法吗?我们错过了什么吗?

任何反馈将是非常感激的…

我认为,没有更好的解决方案来删除/清除ViewScopedBeans在SPA(单页应用程序)比你的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,你找到了或者你用别的方法了吗?

相关内容

  • 没有找到相关文章

最新更新