在视图之间共享组件 - 如何改进我的设计?

时间:2014-08-04 14:37:34

标签: jsf primefaces jsf-2.2

我正在开发一个JSF webapp,目的是包装一个命令行程序。 其主要功能之一是能够在用户之间共享会话(例如,用于课程目的),以便在将输入发送到应用程序的实例时,将输出发送给此会话的每个订阅者。

作为这种设计的结果,webapp主要由视图范围的bean组成,它将请求命令行应用程序的控制器。 它还被选择用于识别具有URL片段的会话(例如,mydomain / myapp /#SESSIONID),以便使用具有相同片段的URL的任何人将共享输入和输出,使用其自己的视图实例-scoped bean但共享相同的控制器

为了将结果推送给所有订阅者,我使用的是Primefaces Push。结果主要是必须附加到webapp终端的文本,但是一些命令导致编程创建JSF组件。 为了处理这个问题,我只是将这些组件渲染为我发送给所有订阅者的字符串。

然后,我意识到为了处理来自组件(以及来自每个订户)的ajax请求,需要将关联的UIComponent添加到的上下文中的UIViewRoot (不要)知道如何表达这个)每个视图范围bean。

事实上,我首先尝试绑定一个普通容器" (一个UIForm)到视图范围bean的属性,我将在其中放置以编程方式创建的组件,但我显然不得不面对鸡/蛋问题@BalusC talks about in his blog,因为组件在每个都被添加ajax请求。将javax.faces.PARTIAL_STATE_SAVING设置为false也没有帮助(我使用 MyFaces 2.2.5

因此,作为一种解决方法,当控制器需要创建一个新组件时,它基本上将组件的id添加到推送的数据中(在转换为Json的HashMap中),并且所有订阅者将触发(返回)一个remoteCommand到它自己的视图范围bean的实例,以便更新"公共容器"来自它自己的UIViewRoot。

这确实有效,但我不喜欢这种做法!

所以:

  1. 是否可以处理存储在不同HTTP会话中的视图范围bean(具有相同名称)之间的这种共享?我在@BalusC中引用this answer ...也许在玩javax.faces.ViewState - 它甚至可以吗?

  2. 是否有一个神奇的"我可以使用的当前视图范围的bean的范围?

  3. 我宁愿使用完全不同的设计吗?

  4. 谢谢!

1 个答案:

答案 0 :(得分:0)

如果您希望在所有应用程序用户之间共享数据,则可以使用应用程序范围。

如果您仍想使用视图范围,则可以将视图范围与另一个应用程序范围连接,如下所示:

ApplicationView appView = BeanUtil.findBean("applicationView", FacesContext.getCurrentInstance());

import javax.faces.context.FacesContext;

公共类BeanUtil {

@SuppressWarnings("unchecked")
public static <T> T findBean(String beanName, FacesContext context) {
    return (T) context.getApplication().evaluateExpressionGet(context,
            "#{" + beanName + "}", Object.class);
}

}