You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Simon Kitching <sk...@obsidium.com> on 2005/11/29 02:52:19 UTC
UIData: does _rowState get serialized with view?
Hi,
The UIData uses the "flyweight" pattern so that a single set of
component children for a single row are enough to implement a table with
any number of rows. The state for each row is stored in _rowState.
When a view is serialized, the state for ordinary components is stored.
I presume that the _rowState is also stored at the same time, and for
the same reasons. Among other things I believe this info would be
necessary to re-rended submitted values for input fields if validation
should fail.
But I just can't see anything in the UIData component that saves the
_rowState.
Can anyone give me a hint?
Thanks,
Simon
Re: UIData: does _rowState get serialized with view?
Posted by Mathias Brökelmann <mb...@googlemail.com>.
IMO Simon You are right in every point (like everytime ;)
2005/12/1, Simon Kitching <sk...@obsidium.com>:
> Thanks for the info Mathias.
>
> I'm not personally suggesting that there *is* a need to serialize the
> _rowState. I was just puzzled why it wasn't.
>
> Thanks for pointing out that a component's _submittedValue will be
> restored on postback via processDecodes; I'd not thought about that.
> However the UIInput.saveState method clearly *does* serialize this data
> for standard input components. It looks like *one* of these two is doing
> something wrong...
>
> What will happen if server-size state-saving is used, together with the
> newly introduced feature to save multiple views? The view gets rendered
> to the user who then pushes the "back" button, alters some fields, then
> presses "submit". Even then, the "back" button will restore the values
> displayed by input fields, so it looks to me like _submittedValue is
> still restored correctly. So what's the point of ever saving it in
> UIInput.saveState?
>
> Members _localValueSet and _valid seem to me to fall in the same
> category - stuff that gets reset anyway during processDecodes, so
> there's no point in storing it. Well, storing it *does* make that info
> available during the "restore view" and processDecodes bits, but I can't
> imagine what use anyone would make of that data during those steps.
>
> By the way, the _rowState data only contains saved state for the above
> fields, though the components themselves have many more members. The
> implications of not saving the other fields is interesting. A UIInput
> saves _immediate, _required, _validatorList, _valueChangeListener.
> However the "real" child components of the UIData will cause these
> values to be serialized once, yes? Then during the iteration over the
> rows the real child components take on the "row state" for each row but
> keep the same values from their original instances for these fields.
> That implies that changing any of these fields programmatically while
> rowIndex=N will cause a change to that property for all rows in the
> table, yes? That's ok by me but would be good to document. If you can
> confirm that this paragraph is correct, I'll write the necessary javadoc.
>
> Cheers,
>
> Simon
>
> Mathias Brökelmann wrote:
> > the rowstate is not serialized with the view. If validation fails the
> > submitted value of any input component is rendered in the response.
> > IMO it is not necessary to save the sate of each row if validation
> > fails since the values are submitted again through the next request.
> >
> > In any case saving this rowstate value would not save the complete
> > state for every component in the row since saveState/restoreState is
> > not called for the components. Only EditableValueHolder components and
> > their current values of the attributes value, submittedvalue, valid
> > and localvalueset are saved in this state. Any other stateful
> > component in a datatable can not be used anyway (its state would not
> > be saved for each row between requests).
> >
> > To make saving the state for each row work for every component we
> > would need to implement UIData.saveState/restoreState to iterate
> > through the rows and call processSaveState/processRestoreState for
> > each uicolumn and serialize this with the view. This would make every
> > component work inside a datatable. But I think we need to keep in mind
> > that this may produce a really big state which must be rendered in the
> > response if client side state is used and the datatable contains a lot
> > of rows.
> >
> > I suggest to implement it in t:datatable with an aditional switch
> > parameter. So users who need it can enable this rowstate saving
> > between requests.
> >
> > 2005/11/29, Manfred Geiler <ma...@gmail.com>:
> >> That's a perfect question and an important issue.
> >> Indeed there was such a "save descendant states" logic in my original
> >> UIData code. As I remember this was one of the more complex parts.
> >> States where only to be saved when all children where valid, and so
> >> on. Well, this logic has vanished during the refactoring by Mathias
> >> Broekelmann.
> >>
> >> Mathias, can you please disclose your rationale to drop this?!
> >>
> >> Thanks,
> >> Manfred
> >>
> >>
> >> 2005/11/29, Simon Kitching <sk...@obsidium.com>:
> >>> Hi,
> >>>
> >>> The UIData uses the "flyweight" pattern so that a single set of
> >>> component children for a single row are enough to implement a table with
> >>> any number of rows. The state for each row is stored in _rowState.
> >>>
> >>> When a view is serialized, the state for ordinary components is stored.
> >>> I presume that the _rowState is also stored at the same time, and for
> >>> the same reasons. Among other things I believe this info would be
> >>> necessary to re-rended submitted values for input fields if validation
> >>> should fail.
> >>>
> >>> But I just can't see anything in the UIData component that saves the
> >>> _rowState.
> >>>
> >>> Can anyone give me a hint?
> >>>
> >>> Thanks,
> >>>
> >>> Simon
> >>>
> >
> >
> > --
> > Mathias
> >
>
>
--
Mathias
Re: UIData: does _rowState get serialized with view?
Posted by Simon Kitching <sk...@obsidium.com>.
Thanks for the info Mathias.
I'm not personally suggesting that there *is* a need to serialize the
_rowState. I was just puzzled why it wasn't.
Thanks for pointing out that a component's _submittedValue will be
restored on postback via processDecodes; I'd not thought about that.
However the UIInput.saveState method clearly *does* serialize this data
for standard input components. It looks like *one* of these two is doing
something wrong...
What will happen if server-size state-saving is used, together with the
newly introduced feature to save multiple views? The view gets rendered
to the user who then pushes the "back" button, alters some fields, then
presses "submit". Even then, the "back" button will restore the values
displayed by input fields, so it looks to me like _submittedValue is
still restored correctly. So what's the point of ever saving it in
UIInput.saveState?
Members _localValueSet and _valid seem to me to fall in the same
category - stuff that gets reset anyway during processDecodes, so
there's no point in storing it. Well, storing it *does* make that info
available during the "restore view" and processDecodes bits, but I can't
imagine what use anyone would make of that data during those steps.
By the way, the _rowState data only contains saved state for the above
fields, though the components themselves have many more members. The
implications of not saving the other fields is interesting. A UIInput
saves _immediate, _required, _validatorList, _valueChangeListener.
However the "real" child components of the UIData will cause these
values to be serialized once, yes? Then during the iteration over the
rows the real child components take on the "row state" for each row but
keep the same values from their original instances for these fields.
That implies that changing any of these fields programmatically while
rowIndex=N will cause a change to that property for all rows in the
table, yes? That's ok by me but would be good to document. If you can
confirm that this paragraph is correct, I'll write the necessary javadoc.
Cheers,
Simon
Mathias Brökelmann wrote:
> the rowstate is not serialized with the view. If validation fails the
> submitted value of any input component is rendered in the response.
> IMO it is not necessary to save the sate of each row if validation
> fails since the values are submitted again through the next request.
>
> In any case saving this rowstate value would not save the complete
> state for every component in the row since saveState/restoreState is
> not called for the components. Only EditableValueHolder components and
> their current values of the attributes value, submittedvalue, valid
> and localvalueset are saved in this state. Any other stateful
> component in a datatable can not be used anyway (its state would not
> be saved for each row between requests).
>
> To make saving the state for each row work for every component we
> would need to implement UIData.saveState/restoreState to iterate
> through the rows and call processSaveState/processRestoreState for
> each uicolumn and serialize this with the view. This would make every
> component work inside a datatable. But I think we need to keep in mind
> that this may produce a really big state which must be rendered in the
> response if client side state is used and the datatable contains a lot
> of rows.
>
> I suggest to implement it in t:datatable with an aditional switch
> parameter. So users who need it can enable this rowstate saving
> between requests.
>
> 2005/11/29, Manfred Geiler <ma...@gmail.com>:
>> That's a perfect question and an important issue.
>> Indeed there was such a "save descendant states" logic in my original
>> UIData code. As I remember this was one of the more complex parts.
>> States where only to be saved when all children where valid, and so
>> on. Well, this logic has vanished during the refactoring by Mathias
>> Broekelmann.
>>
>> Mathias, can you please disclose your rationale to drop this?!
>>
>> Thanks,
>> Manfred
>>
>>
>> 2005/11/29, Simon Kitching <sk...@obsidium.com>:
>>> Hi,
>>>
>>> The UIData uses the "flyweight" pattern so that a single set of
>>> component children for a single row are enough to implement a table with
>>> any number of rows. The state for each row is stored in _rowState.
>>>
>>> When a view is serialized, the state for ordinary components is stored.
>>> I presume that the _rowState is also stored at the same time, and for
>>> the same reasons. Among other things I believe this info would be
>>> necessary to re-rended submitted values for input fields if validation
>>> should fail.
>>>
>>> But I just can't see anything in the UIData component that saves the
>>> _rowState.
>>>
>>> Can anyone give me a hint?
>>>
>>> Thanks,
>>>
>>> Simon
>>>
>
>
> --
> Mathias
>
Re: UIData: does _rowState get serialized with view?
Posted by Adam Winer <aw...@gmail.com>.
On 11/30/05, Simon Kitching <sk...@obsidium.com> wrote:
> > Basically, UIInput *does* need to include the submitted value in
> > saveState(), and UIData does need to save _rowState.
>
> So would saving the state if-and-only-if rendered=false work around
> this? For most cases the component would be rendered, so saved state
> would not be needed.
No, you need to save the state whether or not the component
is rendered, because you might programatically toggle
"rendered" on and then off and need the state; conversely,
a componet might not have its "encodeXyz" mehod called
even though "rendered" is true for it and all of its parents,
because a parent might choose not to render a child.
> > BTW, an independent reason why you have to save _rowState:
> > if you have component in a table (checkboxes, say) that are
> > not EL bound, but simply store their value locally, even though
> > you might successfully get the value resubmitted on a subsequent
> > request, you'll get lots of incorrect ValueChangeEvents since
> > the prior value has been forgotten.
>
> So would it be adequate to also save state for components where the
> "value" attribute is a literal (not an EL expression)? Again, this would
> seem to make it unnecessary to save state in *most* cases.
No, it's not sufficient; the examples get a little more contrived,
but you really do have to take the hit of saving this state if
you want correct behavior.
-- Adam
Re: UIData: does _rowState get serialized with view?
Posted by Simon Kitching <sk...@obsidium.com>.
Adam Winer wrote:
> On 11/30/05, Mathias Brökelmann <mb...@googlemail.com> wrote:
>> the rowstate is not serialized with the view. If validation fails the
>> submitted value of any input component is rendered in the response.
>> IMO it is not necessary to save the sate of each row if validation
>> fails since the values are submitted again through the next request.
>
> This is not guaranteed. Take the following hierarchy (ignoring table, for now):
>
> disclosure component
> input field
>
> By a "disclosure" component, I mean one that can toggle open and shut.
> When it's open, the input field is visible, when it's not the input field
> is not rendered at all (I'm talking a server-side component here, not
> a client-side CSS toggling thing). And let's assume that the server-side
> event is "immediate" - it doesn't do validation, etc., but just toggles
> visibility.
>
> So, you:
> 1. Enter a value
> 2. Click the disclosure component closed (i.e., a submit)
> 3. Reopen the disclosure component (i.e., another submit)
>
> If you did not save "submittedValue", the value you typed in step #1
> is gone. That's because in step #3 the field is hidden - and therefore
> your statement that "the values are submitted again through the next
> request" is false.
>
> Basically, UIInput *does* need to include the submitted value in
> saveState(), and UIData does need to save _rowState.
So would saving the state if-and-only-if rendered=false work around
this? For most cases the component would be rendered, so saved state
would not be needed.
>
> BTW, an independent reason why you have to save _rowState:
> if you have component in a table (checkboxes, say) that are
> not EL bound, but simply store their value locally, even though
> you might successfully get the value resubmitted on a subsequent
> request, you'll get lots of incorrect ValueChangeEvents since
> the prior value has been forgotten.
So would it be adequate to also save state for components where the
"value" attribute is a literal (not an EL expression)? Again, this would
seem to make it unnecessary to save state in *most* cases.
Cheers,
Simon
Re: UIData: does _rowState get serialized with view?
Posted by Adam Winer <aw...@gmail.com>.
On 12/1/05, Mathias Brökelmann <mb...@googlemail.com> wrote:
> @Manfred I see the problem but I don`t think that this can be solved
> by jsf and myfaces. I try to explain why:
>
> Let us take your example. What happens if the user enters some values
> into the input form but don´t submit it and additionally enters
> something into the online help form and submits the online help form.
> The values of the input form are lost anyway (regardless if we try to
> save them) if the user has not submitted these values before
> submitting the online help form. We wouldn't solve this if we save the
> submitted value in the view state.
True, it only fixes half the problem.
> IMO the users who have such a page should simply but both the input
> form an the online help form into a single form. That's more a problem
> if they use includes for the online help section and have a form in
> this include. But why not having a single form for the entire page?
In general, users should use a single form for the entire page. The
biggest problem that results is that there's no way to have separate
validation blocks within a page. ADF Faces has a subform component
that adds that capability within a single form.
Many users are, unfortunately, stuck in an old HTML mindset and
are unwilling to use single forms for the entire page.
-- Adam
Re: UIData: does _rowState get serialized with view?
Posted by Mathias Brökelmann <mb...@googlemail.com>.
@Manfred I see the problem but I don`t think that this can be solved
by jsf and myfaces. I try to explain why:
Let us take your example. What happens if the user enters some values
into the input form but don´t submit it and additionally enters
something into the online help form and submits the online help form.
The values of the input form are lost anyway (regardless if we try to
save them) if the user has not submitted these values before
submitting the online help form. We wouldn't solve this if we save the
submitted value in the view state.
IMO the users who have such a page should simply but both the input
form an the online help form into a single form. That's more a problem
if they use includes for the online help section and have a form in
this include. But why not having a single form for the entire page?
2005/12/1, Manfred Geiler <ma...@gmail.com>:
> Yes, as Adam pointed out the value state of a component always MUST be
> saved as long as the model could not be have been updated with a valid
> value.
> Please keep in mind: The values of a component are NOT GUARANTEED to
> be submitted upon the next request. To give you a practical example,
> imagine two forms on one page: For instance one input form and one
> online help form in kind of a toolbox component on the right margin.
> The user entered something wrong and got an error message for one of
> the entry fields. Now he wants to know why and does a lookup in the
> online help toolbox - ie. he enters a value in the online help search
> field and does a submit - if he is lucky he finds what he has looked
> for. But certainly (if MyFaces did not save the values) he lost all
> his inputs in the data form - which makes him shout loud for sure!
> ;-)
>
> Mathias, this worked before the major UIData refactoring. Can you
> please revise your changes and rethink your motivation to remove the
> save rowstates logic?
>
> Thanks,
> Manfred
>
>
>
> 2005/12/1, Adam Winer <aw...@gmail.com>:
> > On 11/30/05, Mathias Brökelmann <mb...@googlemail.com> wrote:
> > > the rowstate is not serialized with the view. If validation fails the
> > > submitted value of any input component is rendered in the response.
> > > IMO it is not necessary to save the sate of each row if validation
> > > fails since the values are submitted again through the next request.
> >
> > This is not guaranteed. Take the following hierarchy (ignoring table, for now):
> >
> > disclosure component
> > input field
> >
> > By a "disclosure" component, I mean one that can toggle open and shut.
> > When it's open, the input field is visible, when it's not the input field
> > is not rendered at all (I'm talking a server-side component here, not
> > a client-side CSS toggling thing). And let's assume that the server-side
> > event is "immediate" - it doesn't do validation, etc., but just toggles
> > visibility.
> >
> > So, you:
> > 1. Enter a value
> > 2. Click the disclosure component closed (i.e., a submit)
> > 3. Reopen the disclosure component (i.e., another submit)
> >
> > If you did not save "submittedValue", the value you typed in step #1
> > is gone. That's because in step #3 the field is hidden - and therefore
> > your statement that "the values are submitted again through the next
> > request" is false.
> >
> > Basically, UIInput *does* need to include the submitted value in
> > saveState(), and UIData does need to save _rowState.
> >
> > BTW, an independent reason why you have to save _rowState:
> > if you have component in a table (checkboxes, say) that are
> > not EL bound, but simply store their value locally, even though
> > you might successfully get the value resubmitted on a subsequent
> > request, you'll get lots of incorrect ValueChangeEvents since
> > the prior value has been forgotten.
> >
> > -- Adam
> >
>
--
Mathias
Re: UIData: does _rowState get serialized with view?
Posted by Manfred Geiler <ma...@gmail.com>.
Yes, as Adam pointed out the value state of a component always MUST be
saved as long as the model could not be have been updated with a valid
value.
Please keep in mind: The values of a component are NOT GUARANTEED to
be submitted upon the next request. To give you a practical example,
imagine two forms on one page: For instance one input form and one
online help form in kind of a toolbox component on the right margin.
The user entered something wrong and got an error message for one of
the entry fields. Now he wants to know why and does a lookup in the
online help toolbox - ie. he enters a value in the online help search
field and does a submit - if he is lucky he finds what he has looked
for. But certainly (if MyFaces did not save the values) he lost all
his inputs in the data form - which makes him shout loud for sure!
;-)
Mathias, this worked before the major UIData refactoring. Can you
please revise your changes and rethink your motivation to remove the
save rowstates logic?
Thanks,
Manfred
2005/12/1, Adam Winer <aw...@gmail.com>:
> On 11/30/05, Mathias Brökelmann <mb...@googlemail.com> wrote:
> > the rowstate is not serialized with the view. If validation fails the
> > submitted value of any input component is rendered in the response.
> > IMO it is not necessary to save the sate of each row if validation
> > fails since the values are submitted again through the next request.
>
> This is not guaranteed. Take the following hierarchy (ignoring table, for now):
>
> disclosure component
> input field
>
> By a "disclosure" component, I mean one that can toggle open and shut.
> When it's open, the input field is visible, when it's not the input field
> is not rendered at all (I'm talking a server-side component here, not
> a client-side CSS toggling thing). And let's assume that the server-side
> event is "immediate" - it doesn't do validation, etc., but just toggles
> visibility.
>
> So, you:
> 1. Enter a value
> 2. Click the disclosure component closed (i.e., a submit)
> 3. Reopen the disclosure component (i.e., another submit)
>
> If you did not save "submittedValue", the value you typed in step #1
> is gone. That's because in step #3 the field is hidden - and therefore
> your statement that "the values are submitted again through the next
> request" is false.
>
> Basically, UIInput *does* need to include the submitted value in
> saveState(), and UIData does need to save _rowState.
>
> BTW, an independent reason why you have to save _rowState:
> if you have component in a table (checkboxes, say) that are
> not EL bound, but simply store their value locally, even though
> you might successfully get the value resubmitted on a subsequent
> request, you'll get lots of incorrect ValueChangeEvents since
> the prior value has been forgotten.
>
> -- Adam
>
Re: UIData: does _rowState get serialized with view?
Posted by Adam Winer <aw...@gmail.com>.
On 11/30/05, Mathias Brökelmann <mb...@googlemail.com> wrote:
> the rowstate is not serialized with the view. If validation fails the
> submitted value of any input component is rendered in the response.
> IMO it is not necessary to save the sate of each row if validation
> fails since the values are submitted again through the next request.
This is not guaranteed. Take the following hierarchy (ignoring table, for now):
disclosure component
input field
By a "disclosure" component, I mean one that can toggle open and shut.
When it's open, the input field is visible, when it's not the input field
is not rendered at all (I'm talking a server-side component here, not
a client-side CSS toggling thing). And let's assume that the server-side
event is "immediate" - it doesn't do validation, etc., but just toggles
visibility.
So, you:
1. Enter a value
2. Click the disclosure component closed (i.e., a submit)
3. Reopen the disclosure component (i.e., another submit)
If you did not save "submittedValue", the value you typed in step #1
is gone. That's because in step #3 the field is hidden - and therefore
your statement that "the values are submitted again through the next
request" is false.
Basically, UIInput *does* need to include the submitted value in
saveState(), and UIData does need to save _rowState.
BTW, an independent reason why you have to save _rowState:
if you have component in a table (checkboxes, say) that are
not EL bound, but simply store their value locally, even though
you might successfully get the value resubmitted on a subsequent
request, you'll get lots of incorrect ValueChangeEvents since
the prior value has been forgotten.
-- Adam
Re: UIData: does _rowState get serialized with view?
Posted by Mathias Brökelmann <mb...@googlemail.com>.
the rowstate is not serialized with the view. If validation fails the
submitted value of any input component is rendered in the response.
IMO it is not necessary to save the sate of each row if validation
fails since the values are submitted again through the next request.
In any case saving this rowstate value would not save the complete
state for every component in the row since saveState/restoreState is
not called for the components. Only EditableValueHolder components and
their current values of the attributes value, submittedvalue, valid
and localvalueset are saved in this state. Any other stateful
component in a datatable can not be used anyway (its state would not
be saved for each row between requests).
To make saving the state for each row work for every component we
would need to implement UIData.saveState/restoreState to iterate
through the rows and call processSaveState/processRestoreState for
each uicolumn and serialize this with the view. This would make every
component work inside a datatable. But I think we need to keep in mind
that this may produce a really big state which must be rendered in the
response if client side state is used and the datatable contains a lot
of rows.
I suggest to implement it in t:datatable with an aditional switch
parameter. So users who need it can enable this rowstate saving
between requests.
2005/11/29, Manfred Geiler <ma...@gmail.com>:
> That's a perfect question and an important issue.
> Indeed there was such a "save descendant states" logic in my original
> UIData code. As I remember this was one of the more complex parts.
> States where only to be saved when all children where valid, and so
> on. Well, this logic has vanished during the refactoring by Mathias
> Broekelmann.
>
> Mathias, can you please disclose your rationale to drop this?!
>
> Thanks,
> Manfred
>
>
> 2005/11/29, Simon Kitching <sk...@obsidium.com>:
> > Hi,
> >
> > The UIData uses the "flyweight" pattern so that a single set of
> > component children for a single row are enough to implement a table with
> > any number of rows. The state for each row is stored in _rowState.
> >
> > When a view is serialized, the state for ordinary components is stored.
> > I presume that the _rowState is also stored at the same time, and for
> > the same reasons. Among other things I believe this info would be
> > necessary to re-rended submitted values for input fields if validation
> > should fail.
> >
> > But I just can't see anything in the UIData component that saves the
> > _rowState.
> >
> > Can anyone give me a hint?
> >
> > Thanks,
> >
> > Simon
> >
>
--
Mathias
Re: UIData: does _rowState get serialized with view?
Posted by Manfred Geiler <ma...@gmail.com>.
That's a perfect question and an important issue.
Indeed there was such a "save descendant states" logic in my original
UIData code. As I remember this was one of the more complex parts.
States where only to be saved when all children where valid, and so
on. Well, this logic has vanished during the refactoring by Mathias
Broekelmann.
Mathias, can you please disclose your rationale to drop this?!
Thanks,
Manfred
2005/11/29, Simon Kitching <sk...@obsidium.com>:
> Hi,
>
> The UIData uses the "flyweight" pattern so that a single set of
> component children for a single row are enough to implement a table with
> any number of rows. The state for each row is stored in _rowState.
>
> When a view is serialized, the state for ordinary components is stored.
> I presume that the _rowState is also stored at the same time, and for
> the same reasons. Among other things I believe this info would be
> necessary to re-rended submitted values for input fields if validation
> should fail.
>
> But I just can't see anything in the UIData component that saves the
> _rowState.
>
> Can anyone give me a hint?
>
> Thanks,
>
> Simon
>