Search code examples
jsf-2codi

Open a new tab don't create new ViewAccessScoped bean


I have a sample use case: I have an edit page that use GET parameter "id". eg. edit?id=1

This edit page is backed by a ViewAccessScoped (CODI) Bean.

In this edit page, I have a datatable with links that link to the same "edit" page, but with another id. (eg. edit?id=2)

<h:link value="#{mecaPart.id}" outcome="edit" target="_blank">
    <f:param name="id" value="#{mecaPart.id}" />
</h:link>

The problem, is that the window open correctly, but it is the same bean that is used! And so I am editing the same part...

I have placed a log in @PostConstruct, and it is the same bean reference that is called multiple times. (even with the new ID!)

My question, how can I tell JSF to create a new ViewAccessScoped backing bean when I click the link, and not re-use the actually used one?


Solution

  • Finally, I discovered that @ViewScoped CODI bean did not preserved the backing bean from page refresh. So, I have to use ViewAccessScoped.

    According to Gerhard Petracek: http://os890.blogspot.fr/2011/08/scopes-view-scope-vs-view-access-scope.html

    the view-scope of jsf2+ is bound to a concrete jsf page. that means: as soon as you navigate to a different page, the state gets lost. that's better than nothing, but not useful for a lot of use-cases. the main use-case which needs it are ajax-requests on a page and the data used by them aren't needed on other pages, but it's pretty easy to break it e.g. with a browser-refresh on a page which stores the data in a view-scoped bean and has no form with input components. (in a previous blog post i described how to use the infrastructure provided by codi to create a session based view-scope to overcome such disadvantages cause by storing view scoped beans as part of the tree-state.)

    like with the view-scope view-access-scoped beans are available on a page, but they also exist for the next page. that means: they are forwarded to the next page and get destroyed autom. if they don't get used during the first request of the next page. that's e.g. useful for wizards. if you have a wizard page which doesn't use the bean or you have to support the possibility to interrupt a wizard, you can use the grouped-conversation scope (and even the window-scope) provided by codi. however, due to the powerful api of codi you can also destroy the scope manually at any time (if needed).

    So, to solve the problem of opening a new tab with another "ID", I had to set "CODI Client Side WindowHandler", according to the CODI Wiki. https://cwiki.apache.org/confluence/display/EXTCDI/JSF+WindowHandler

    So I added:

    <alternatives>
         <class>org.apache.myfaces.extensions.cdi.jsf.impl.scope.conversation.ClientSideWindowHandler</class>
    </alternatives>
    

    To the file beans.xml, and I used @ViewAccessScoped. Everything is working smoothly now.