|
Hi Yee, When I needed this I tried using the custom
navigation handler, but since it did not save the state I moved to this method.
The main reason being that I did not want the historyManager stack to be saved
in the session because that, as you correctly state, could cause memory
problems. Instead, I save the historyManager in the (client side) viewState
using the t:saveState component. Furthermore, I do not need the history manager
on all my pages, only on “sub-dialogs”. So once I exit such a
dialog the historyManager is forgotten. By default, backing beans are not part of
the viewState, so no problems with session scoped beans. My request scoped
beans store their state using the t:saveState component (if they need to) and thus
become part of the viewState. When my request scope beans have references to
other beans I usualy create a “state” property that is saved and
restored with the t:saveState component (instead of saving the whole bean).
This prevent the references from being saved and restored too. Another advantage of saving the state is
that the whole interface is restored, not just the page you were viewing. So
that means your input in for example text-fields, select-lists, radio buttons,
etc. are restored plus possibly any unsaved data you were editing that was
stored in t:saveState backing beans or properties. This is actually quite
poweful. It might be interesting to convert this
solution to a navigation handler. That might make it more pluggable. Kind regards, Van: Yee CN
[mailto:[EMAIL PROTECTED] Hi I find your approach very
interesting. I have not thought about saving the viewState at all. Thinking more about it,
saving viewState would work for request scoped backing beans – but I
think it could cause inconsistencies with session scoped backing beans, for
example if the bean is shared with other pages, or if we loop to the same page
twice. So for the scheme to work we would have to save both the viewState plus
the backing beans. Did you do anything to
limit the size of the stack so it won’t cumulate references and prevent
garbage collection? What problems did you had
with navigation handler? Since the reply from Onur I did some google search and
found the following blog http://jroller.com/comments/cenkcivici/Weblog/custom_jsf_navigation_handler_for
detailing an approach using navigation handler. That approach only stores the navigation
in the stack so it requires all beans to be session scope. Also
‘back’ will not guarantee to get back the same state. But I think
the scheme could be modified to save the viewState so it will work for request
scoped beans. I am just beginning to
learn about custom navigation handler so I would appreciate if you could share
your experiences. Thanks again. Best regards, Yee From:
Hi, I had some trouble doing this in a
navigation handler so I implemented a similar mechanism some time ago and have
been using it succesfully for some time now. It is not exactly what you
describe, but might be just what you need. It basicly works as following: HistoryManager (request scope managed
bean) .addCurrentViewState() Pushes
viewstate on internal stack .returnToLast() Pops and
restores last viewstate from stack Each button-action that needs to save the
current state has the following ActionListener: AddViewStateListener .processAction() Calls
historyManager.addCurrentViewState() The pages following the button-action
store the historyManager using <t:saveState/> tags. To return to the
previous state the a button-action can call
“historyManager.returnToLast”. We also have a HistoryMarkers bean
(session scope) that allows you to mark a specific state and return to it later
by calling a specific url. We use this to return to our application after
redirecting to an external website url. If there is any interest for this
mechanism we could put these classes in the myfaces sandbox. Kind regards, Van: Yee CN [mailto:[EMAIL PROTECTED]
Hi, I am thinking of providing a ‘back’
button on all my pages. Below is a sketch on how I intended to do it, but
before embarking on it I would like to know whether anybody has done similar
and to hear from you Gurus whether my approach is workable. 1) I have a stack<backingBean,
nagivgationResult> to store the pages being visited and the associated
backing bean. The stack will be limited to store
(say) the last 10 pages visited, so it won’t grow continuously. I think a
circular list could probably be used for this. 2) A phase listener will push the current
page’s backing bean and navigation to the stack; it will happen at the AFTER RENDER_RESPONSE phase. 3) The ‘back’ button will pop the stack
– restores the backing bean and navigates back to the page concerned. 4) Some pages can be marked to not to participate in
this scheme. I am assuming a) the beans are in request scope, b)
there is only one backing bean per page. For session scope beans I would have to serialize the
bean. Please – any comments? Best regards, Yee // getting an restoring a manage bean public static Object getManagedBean(String beanName)
{
Object o = getValueBinding( “#{“ + beanName + “}”
).getValue(FacesContext.getCurrentInstance());
return o; }
public static void setManageBean(String beanName,
Object bean) {
getValueBinding( “#{“ + beanName + “}”
).setValue(FacesContext.getCurrentInstance(), bean); } // some helper methods private static Application getApplication() {
ApplicationFactory appFactory =
(ApplicationFactory)FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
return appFactory.getApplication(); }
private static ValueBinding getValueBinding(String
el) {
return getApplication().createValueBinding(el); }
private static Object getElValue(String el) {
return getValueBinding(el).getValue(FacesContext.getCurrentInstance()); }
|

