Emil Sierżęga
Emil Sierżęga

Reputation: 2081

How to change the order of creation/restoring managed beans?

I have a complex problem with order of 'JSF bean life cycle actions'.

I have two beans with different scopes. The first, let's call it, managerBean is session scope bean. The second one, someBean has view scope (someBean really is many different beans). ManagerBean takes some action once per page loading and few others view scope beans are using the results of this action in their constructors.

Everything was working just fine until I've started getting forms IDs in xhtml files from java beans. Now action from managerBean is taken after someBean is created and I'm getting expected result only when the page is reloaded (on refresh, so someBean is using the first results of ManagerBean work).

This is how it looks like now:

<!-- mainTemplate is a main templete of the page which is rendered once
     per page view (every other actions are taken via ajax). This is a place
     of ManagerBean work after re rendering the page -->
<ui:composition template="/mainTemplate.xhtml"> 
    <ui:define name="mainContent">

        <h:form id="#{someBean.formID}">
            some inputs
        </h:form>

        (...)
    </ui:define>
</ui:composition>

So when form id was constant String everything worked like I want and now it doesn't. It looks like JSF must calculate ID first and take any other after this (including ManagerBean action).

My question is: Is there a way to change this situation? If something isn't clear enought, please ask. I was trying to simplify the problem because it has many factors. Maybe all my thinking is wrong (the way I want to take some action per page and some actions after it).

Any help will be good!

Upvotes: 0

Views: 401

Answers (1)

BalusC
BalusC

Reputation: 1109132

The id (and binding) attribute of a JSF UI component is evaluated during view build time. The view build time is that moment when the XHTML source code is turned into a JSF UI component tree. All other attributes of a JSF UI component like value and all events like preRenderView are evaluated/executed after the view build time, usually during view render time (when the JSF UI component tree needs to produce HTML output). This is not something which you can change by just turning a setting or so. It's just the way how JSF works. You can't render something which isn't built yet. You can only change this by writing code the right way.

I can't think of any real world scenario why you need to make the ID attribute dynamic like this. If it were inside a <c:forEach>, or part of dynamic component generation, then okay, but this seems just to be a static form. So I would in first place recommend to forget it and just hardcode the ID in the view and rely on other variables (perhaps a hidden input field? depends all on concrete functional requirement which isn't mentioned anywhere in the question nor guessable based on the code posted so far).

If you really need to make it dynamic, then you need to split the formID property off from the view scoped bean and move it to a different and independent bean, perhaps an application scoped one.

See also:

Upvotes: 1

Related Questions