Hi Nico,

 

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: Nico Krijnen [mailto:[EMAIL PROTECTED]
Sent: Friday, 6 January 2006 5:58 PM
To: 'MyFaces Discussion'; [EMAIL PROTECTED]
Subject: RE: How to implement 'back' button

 

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,
Nico Krijnen

GRAPHit B.V.
The Netherlands


Van: Yee CN [mailto:[EMAIL PROTECTED]
Verzonden: vrijdag 6 januari 2006 10:27
Aan: 'MyFaces Discussion'
Onderwerp: How to implement 'back' button

 

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());

}

           

 

Reply via email to