Sharing components between views - how to improve my design?

扶醉桌前 提交于 2019-12-21 20:49:12

问题


I'm working on a JSF webapp which purpose is to wrap a command-line program. One of its main functionality is the ability to share a session between users (eg. for courses purpose), so that when an input is sent to an instance of the application, the output sent to every subscriber for this session.

As a result of this design, the webapp is mainly composed of a view-scoped bean which will request a controller of the command-line application. It has also been chosen to identify a session with the URL fragment (eg. mydomain/myapp/#SESSIONID), so that anyone using the URL with the same fragment will share inputs and outputs, using its own instance of the view-scoped bean but sharing the same controller

In order to push results to all subscribers, I'm using Primefaces Push. Results are primarily text that has to be appened to the webapp's terminal, but some commands lead to the programmatic creation of a JSF component. In order to handle this, I just render these components to a string that I send to all subscribers.

Then, I realized that in order to handle ajax requests from components (and from every subscriber), the associated UIComponent needs to be added to the UIViewRoot in the context of (don't know how to express this) each view-scope bean.

As a matter of fact, I first tried to bind a "common container" (a UIForm) to a property of the view scoped bean, in which I would put the programmatically created components, but I obviously had to face the chicken/egg issue @BalusC talks about in his blog, because the component was added again on each ajax request. Setting javax.faces.PARTIAL_STATE_SAVING to false didn't help either (I'm using MyFaces 2.2.5)

So, as somewhat of a workaround, when the controller needs to create a new component, it basically adds the id of the component to the data pushed (in a HashMap converted to Json), and all subscribers will trigger (back) a remoteCommand to its own instance of the view-scoped bean, in order to update the "common container" from its own UIViewRoot.

This does work, but I don't like this way of doing it!

So:

  1. would it be possible to handle this kind of sharing between view-scope beans (with the same name) which are stored in different HTTP sessions? I'm refering to this answer from @BalusC... maybe playing with javax.faces.ViewState - would it even be possible?

  2. Is there a "magical" scope for my currently-view-scoped bean I could use?

  3. Shall I rather use a completely different design?

Thanks!


回答1:


If you want share data between all your application users you can use application scope.

If you still want to use view scope, you can connect your view scope with another application scope like this:

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

import javax.faces.context.FacesContext;

public class BeanUtil {

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

}



来源:https://stackoverflow.com/questions/25121232/sharing-components-between-views-how-to-improve-my-design

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!