myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marek Zachara <marek.zach...@telperion.pl>
Subject Re: Action not called when the value for rendered attribute changes
Date Sun, 24 Dec 2006 08:40:19 GMT
On Sunday 24 December 2006 00:11, Craig McClanahan wrote:
> On 12/23/06, Marek Zachara <marek.zachara@telperion.pl> wrote:
> > certainly, though it boils down to extremely simple scenario:
> >
> > bean1 (scope="request"):
> > public String testAction() {
> >         System.out.print("Test Action");
> >         return null;
> > }
> >
> > bean2 (scope="request"):
> > private boolean show = false;
> > public setShow() {
> >         this.showMe = true;
> > }
> > public boolean showMe() {
> >         return this.showMe;
> > }
> >
> > jsf page:
> > ....
> > some code that calls bean2.setShow
> > ....
> > <h:commandButton value="Test Me" action="#{bean1.testAction}"
> > rendered="#{bean2.showMe}" />
> >
> >
> > the above is enough to reporoduce the behaviour (nothing will
> > be written in the log/stdout
>
> Actually, this behavior is "by design" and you need to adapt your
> application logic to it.
>
> The "rendered" property is used in *two* places  for command and input
> components (including <h:commandButton> here):
>
> * During Render Response, to determine whether or not to render
>   the component at all.
>
> * During Apply Request Values on the subsequent postback, to
>   determine whether or not the input value should be decoded
>   and processed.  (The "disabled" property, when present, is also
>   a part of this test but isn't relevant for your example use case.)
>
> It's the second one that is biting you with your current logic -- as the
> component tree is getting reconstructed during Restore View, the "#{
> bean2.showMe}" expression is evaluated (creating a new instance of Bean2)
> ... and that returns your default value of "false".
>
> To do what you are trying to do, you need to have the calculated value for
> the "showMe" property survive from one request to the next.  A few ways to
> make that happen:
>
> * As suggested, use <t:saveState> (although I'm on record
>   as not liking this, because it mixes business logic and presentation
>   logic in the page :-).
>
> * Put bean2 in session scope instead of request scope.  That
>   way, the previously set value will be remembered.
>
this solution does not seem practical in my case as i have quite a few
beans that would have to be put into session scope - and i certainly
dont want to have them 'hanging around' all the time. So i have
gathered all this rendering attributes into one session bean 
- that way its easier to maintain

> * Instead of using a binding expression for the rendered property,
>   find the component instance and set it directly there.  This works
>   because JSF restores the component tree for you, including the
>   value of all the directly set attributes.  (Anything where you've
>   used an expression is going to cause that expression to be
>   re-evaluated, as we have seen.)
>
i might be missing the idea, but in my case the rendering of certain
command buttons depends on the state of several interacting request beans
so its not just one component that is used for evaluation

Marek

Thank you all for the feedback, though I will still argue this behaviour of 
myfaces does not seem logical :) i mean maybe i should submit it for a 
wishlist? (unless someone is sure its not going to work because of some
core logic that cant be changed)


Mime
View raw message