You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Werner Punz <we...@gmx.at> on 2005/06/28 10:43:24 UTC

Re: x:dataScroller how to preserve the state - finally solved

It seems that I finally have found an easy solution to the problem.

The state of the datamodel and the datscroller seems to be preserved
if there is no explicit forwarding set in the faces-config, thus
only a refresh with different parameters is issued.

I will try to give an example: I have a datatable with a connected
datascroller with a paginator:

The table has a command link somewhere

<h:commandLink action="#{DiffsyschangelogMaster.selectForOperation}">
	<h:outputText id="selected" value="[x]"
			rendered="#{bean.selectedForOperation}" />
	<h:outputText id="notselected" value="[ ]"
		rendered="#{!bean.selectedForOperation}" />
	<f:param name="beanId" value="#{bean.id}" />
</h:commandLink>

The problem is now, if there is an explicit action from 
#{DiffsyschangelogMaster.selectForOperation} value which is covered by 
the faces-config, a full cycle is issued, that means that model
scroller resets to 1 due to internal handling of the objects (there 
seems to be an interim page, which resets the data model position and 
generates new models between encodeBeging and renderChildren, this looks 
like a bug or unwanted sidebehavior to me).

The main difference is if you set the result value to something bogus, 
which is not covered by the faces config... a simple form refresh with 
is issued which recoveres the old model values if the 
preserveDataModel="true" is set to true and hence the scroller position 
is recovered and rendered anew with the old and the changed values.

No patch to the current sourcebase is needed nor do we need a new 
scroller, the existing one seems to do the job just fine.

Werner


Re: Antwort: Re: Antwort: Re: x:dataScroller how to preserve the state - finally solved

Posted by Werner Punz <we...@gmx.at>.
mathias.werlitz@daimlerchrysler.com wrote:
> 
> Thanks for the info. Important to know.
> But I would expect this behavior, because the component and its state 
> should be preserved with the instance in the bean.
The problem is not that the component does not preserve the state, but 
the problem is much deeper in the request cycle.
The problem is, if you send an request which is not covered by the 
faces-config navigation, a simple refresh, the datamodel is basically 
the same between encodebegin and encodechildren

if you do it over a faces-config nav refresh, the datamodel gets 
rendered and then is lost to the scroller, for some strange kind of reason.

So what happens, the state basically is preserved, but the datamodel 
gets lost between two rendering phases.



Antwort: Re: Antwort: Re: x:dataScroller how to preserve the state - finally solved

Posted by ma...@daimlerchrysler.com.
Thanks for the info. Important to know.
But I would expect this behavior, because the component and its state 
should be preserved with the instance in the bean.

Re: Antwort: Re: x:dataScroller how to preserve the state - finally solved

Posted by Werner Punz <we...@gmx.at>.
mathias.werlitz@daimlerchrysler.com wrote:
> 
> Just an idea: you could bind the component itself to a session scoped 
> bean or save that bean with the <x:saveState> component between requests.
> I have not tried this, but I guess that should avoid loosing the state 
> between multiple requests even with page navigation.

Unfortunately that does not work... tried that a while ago.


Antwort: Re: x:dataScroller how to preserve the state - finally solved

Posted by ma...@daimlerchrysler.com.
Just an idea: you could bind the component itself to a session scoped bean 
or save that bean with the <x:saveState> component between requests.
I have not tried this, but I guess that should avoid loosing the state 
between multiple requests even with page navigation.

Re: x:dataScroller how to preserve the state - finally solved

Posted by Werner Punz <we...@gmx.at>.
Enrique Medina wrote:
> Just some clarification...
> 
> I told you to check whether it works with preserveDataModel set to
> false, due to the fact that preserveDataModel set to true does not
> work with checkboxes placed inside the table (as the typical way to
> select some rows to, for example, delete all selected).
> 
> It seems that there is an order problem when MyFaces serializes them
> to preserve the dataModel, so the checkboxes get mixed between
> requests...
> 
That is one of the reasons why I implemented my own event based 
checkboxing system for datatables, as you can see in the code I posted 
before... :-)

The state saving is done via some kind of caching on the backend
side of things, so nothing can get mixed up in my case...


Re: x:dataScroller how to preserve the state - finally solved

Posted by Enrique Medina <e....@gmail.com>.
Just some clarification...

I told you to check whether it works with preserveDataModel set to
false, due to the fact that preserveDataModel set to true does not
work with checkboxes placed inside the table (as the typical way to
select some rows to, for example, delete all selected).

It seems that there is an order problem when MyFaces serializes them
to preserve the dataModel, so the checkboxes get mixed between
requests...

Have you faced that problem?

2005/6/28, Werner Punz <we...@gmx.at>:
> Enrique Medina wrote:
> > Fantastic. NULL tells JSF just to stay in the same page, so it should
> > work as you have tested. But the problem still remains when navigating
> > to another page, doesn't it?
> >
> Yes that is a huge problem, but the problem is bigger than it seems, it
> is basically the old scope problem, which means that you basically loose
> all the values unless you traverse it, because we do not have a scope
> system between request and session, and add to that some weirdness in
> the behavior between the datatable and the scroller and you run into
> this mess.
> 
> Shale can solve that to some degree, but I rather doubt it will solve it
> for the datatable, the problem is sort of much more fundamental.
> 
> I will try to explain what happens and why the values are lost between
> faces-config navigations:
> 
> What happens in a null:
> 
> The values are cleard the form values are refilled, the parameters are
> passed via a submit...
> The datatable is generated
> the scroller is generated does an encodebegin with all the needed
> calculations passes it to the datatable for further reference,
> the datatable is rendered
> and then the scroller does its rendering.
> 
> What happens if you dont do the refresh but a faces-config based traversal:
> 
> The steps until the encodebegin are identical, but then the problem
> arises in between encodebegin and renderchildren, the datamodel is lost
> along the way and a new one is generated, which is not the same as the
> rendered one, thus passing the values, altering the states, etc... does
> not have any effect on the rendering and the table->scroller subsystem
> resets to the first page.
> 
> I tried to fix that, but I ran against my limited knowledge of JSF.
> Probably to fix that a new datatable and scroller maybe a combined
> component has to be implemented.
> Trying to fix it from outside with a bunch of listeners which hook into
> the component definitely wont help neither does altering the scroller
> rendering code, because the problem is nested much much deeper.
> 
>

Re: x:dataScroller how to preserve the state - finally solved

Posted by Werner Punz <we...@gmx.at>.
Enrique Medina wrote:
> Fantastic. NULL tells JSF just to stay in the same page, so it should
> work as you have tested. But the problem still remains when navigating
> to another page, doesn't it?
> 
Yes that is a huge problem, but the problem is bigger than it seems, it 
is basically the old scope problem, which means that you basically loose 
all the values unless you traverse it, because we do not have a scope 
system between request and session, and add to that some weirdness in 
the behavior between the datatable and the scroller and you run into 
this mess.

Shale can solve that to some degree, but I rather doubt it will solve it 
for the datatable, the problem is sort of much more fundamental.

I will try to explain what happens and why the values are lost between 
faces-config navigations:

What happens in a null:

The values are cleard the form values are refilled, the parameters are 
passed via a submit...
The datatable is generated
the scroller is generated does an encodebegin with all the needed 
calculations passes it to the datatable for further reference,
the datatable is rendered
and then the scroller does its rendering.


What happens if you dont do the refresh but a faces-config based traversal:

The steps until the encodebegin are identical, but then the problem 
arises in between encodebegin and renderchildren, the datamodel is lost 
along the way and a new one is generated, which is not the same as the 
rendered one, thus passing the values, altering the states, etc... does 
not have any effect on the rendering and the table->scroller subsystem
resets to the first page.

I tried to fix that, but I ran against my limited knowledge of JSF.
Probably to fix that a new datatable and scroller maybe a combined 
component has to be implemented.
Trying to fix it from outside with a bunch of listeners which hook into 
the component definitely wont help neither does altering the scroller 
rendering code, because the problem is nested much much deeper.


Re: x:dataScroller how to preserve the state - finally solved

Posted by Enrique Medina <e....@gmail.com>.
Fantastic. NULL tells JSF just to stay in the same page, so it should
work as you have tested. But the problem still remains when navigating
to another page, doesn't it?

Thanks Werner.

2005/6/28, Werner Punz <we...@gmx.at>:
> Enrique Medina wrote:
> > Hi Werner,
> >
> > Do you mean that returning NULL from the action method would be sufficient?
> >
> > And another comment, does it work if you set preserveDataModel to false?
> >
> Just tried it out, at least on my system preserveDataModel to false and
> returning a null from the action does not make any difference, the
> system preserves the positional state as long as you dont run into
> any mapped action value (null seems to be covered in this case
> by the subsystem as navigational value)
> 
> So things look pretty good.
> 
>

Re: x:dataScroller how to preserve the state - finally solved

Posted by Werner Punz <we...@gmx.at>.
Enrique Medina wrote:
> Hi Werner,
> 
> Do you mean that returning NULL from the action method would be sufficient?
> 
> And another comment, does it work if you set preserveDataModel to false?
> 
Just tried it out, at least on my system preserveDataModel to false and 
returning a null from the action does not make any difference, the 
system preserves the positional state as long as you dont run into
any mapped action value (null seems to be covered in this case
by the subsystem as navigational value)

So things look pretty good.


Re: x:dataScroller how to preserve the state - finally solved

Posted by Werner Punz <we...@gmx.at>.
Enrique Medina wrote:
> Hi Werner,
> 
> Do you mean that returning NULL from the action method would be sufficient?
> 
not sure if a returning null would not cause a nullpointer, since I am 
working on it now I will give it a try, hold on.

> And another comment, does it work if you set preserveDataModel to false?
> 
I will try it, hold on for a few minutes...

Werner


Re: x:dataScroller how to preserve the state - finally solved

Posted by Enrique Medina <e....@gmail.com>.
Hi Werner,

Do you mean that returning NULL from the action method would be sufficient?

And another comment, does it work if you set preserveDataModel to false?

2005/6/28, Werner Punz <we...@gmx.at>:
> It seems that I finally have found an easy solution to the problem.
> 
> The state of the datamodel and the datscroller seems to be preserved
> if there is no explicit forwarding set in the faces-config, thus
> only a refresh with different parameters is issued.
> 
> I will try to give an example: I have a datatable with a connected
> datascroller with a paginator:
> 
> The table has a command link somewhere
> 
> <h:commandLink action="#{DiffsyschangelogMaster.selectForOperation}">
>         <h:outputText id="selected" value="[x]"
>                         rendered="#{bean.selectedForOperation}" />
>         <h:outputText id="notselected" value="[ ]"
>                 rendered="#{!bean.selectedForOperation}" />
>         <f:param name="beanId" value="#{bean.id}" />
> </h:commandLink>
> 
> The problem is now, if there is an explicit action from
> #{DiffsyschangelogMaster.selectForOperation} value which is covered by
> the faces-config, a full cycle is issued, that means that model
> scroller resets to 1 due to internal handling of the objects (there
> seems to be an interim page, which resets the data model position and
> generates new models between encodeBeging and renderChildren, this looks
> like a bug or unwanted sidebehavior to me).
> 
> The main difference is if you set the result value to something bogus,
> which is not covered by the faces config... a simple form refresh with
> is issued which recoveres the old model values if the
> preserveDataModel="true" is set to true and hence the scroller position
> is recovered and rendered anew with the old and the changed values.
> 
> No patch to the current sourcebase is needed nor do we need a new
> scroller, the existing one seems to do the job just fine.
> 
> Werner
> 
>