You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Simon Kitching <sk...@obsidium.com> on 2005/11/13 23:56:50 UTC

dataTable: why are row states cleared before render?

Hi,

I see that recently some work has been done on implementing a 
"preserveRowStates" flag for the dataTable component.

As is (now) documented, the ancestor UIData component uses the 
"flyweight" pattern so that only one set of child objects is used to 
represent the columns and their contents. As each row is selected via 
setRowIndex, the component state is saved in _rowStates array, and the 
components are reinitialised with the _rowStates entry appropriate for 
the next row.

However unless preserveRowState is set (it is false by default), the 
encodeBegin method discards all row state before rendering begins.

I'm puzzled by this. Why is the row state cleared?

And if row state is going to be ignored, what's the point of saving it 
at all?

Regards,

Simon

Re: dataTable: why are row states cleared before render?

Posted by Simon Kitching <sk...@obsidium.com>.
Mathias Brökelmann wrote:
> You are right in every point.
> 
> more comments inline...

Thanks for the confirmation and explanation Mathias.

I have updated the javadoc for class UIData to contain this information
(and wow, that's one tricky class).

Regards,

Simon

Re: dataTable: why are row states cleared before render?

Posted by Mathias Brökelmann <mb...@googlemail.com>.
You are right in every point.

more comments inline...

2005/11/22, Simon Kitching <sk...@obsidium.com>:
> Hi Mathias,
>
> Are you able to find time to check the info below, and answer the
> question?  Once that is done I can commit this new javadoc for the
> UIData component.
>
> Thanks,  Simon
>
> Simon Kitching wrote:
> > Thanks Mathias.
> >
> > I now realise that (just like an InputText component will re-fetch its
> > bound value before rendering) the UIData needs to re-fetch its DataModel
> > object before rendering. And that when the datamodel object is reloaded
> > the rowState really needs to be recomputed too, as the DataModel may
> > have more elements, less elements, or reordered elements.
> >
> > This is clearly inconvenient for people who want to set properties on
> > the table's child components earlier in the processing, and those people
> > can now set preserveRowState to true if they really need to do this.
> > However the price they pay is that they must not ever change the order
> > of objects in the DataModel.

you can use a valuebinding for preserveRowState which returns false if
the datamodel has structurally changed or returns true if there are no
changes.

> >
> > In the case of controlling the "rendered" attribute for a particular
> > component in a particular row (Grant Smith's case) it would presumably
> > be better to ensure the child components have a value-binding which
> > calculates the rendered attribute on demand rather than try to set
> > rendered state in row components from some action listener method.
> >
> > Have I got the above right?

yes, using the rendered attribute is better for this use case

> >
> > Another question: I must be dense, but what's the reason that a UIData
> > has a *map* of DataModel objects, keyed by the id of the UIData's parent
> > component? Is this some special code to handle the case where a UIData
> > component is "reparented"?

yes, this map is used to map the right datamodel for nested uidata components.

--
Mathias

Re: dataTable: why are row states cleared before render?

Posted by Simon Kitching <sk...@obsidium.com>.
Hi Mathias,

Are you able to find time to check the info below, and answer the 
question?  Once that is done I can commit this new javadoc for the 
UIData component.

Thanks,  Simon

Simon Kitching wrote:
> Thanks Mathias.
> 
> I now realise that (just like an InputText component will re-fetch its 
> bound value before rendering) the UIData needs to re-fetch its DataModel 
> object before rendering. And that when the datamodel object is reloaded 
> the rowState really needs to be recomputed too, as the DataModel may 
> have more elements, less elements, or reordered elements.
> 
> This is clearly inconvenient for people who want to set properties on 
> the table's child components earlier in the processing, and those people 
> can now set preserveRowState to true if they really need to do this. 
> However the price they pay is that they must not ever change the order 
> of objects in the DataModel.
> 
> In the case of controlling the "rendered" attribute for a particular 
> component in a particular row (Grant Smith's case) it would presumably 
> be better to ensure the child components have a value-binding which 
> calculates the rendered attribute on demand rather than try to set 
> rendered state in row components from some action listener method.
> 
> Have I got the above right?
> 
> Another question: I must be dense, but what's the reason that a UIData 
> has a *map* of DataModel objects, keyed by the id of the UIData's parent 
> component? Is this some special code to handle the case where a UIData 
> component is "reparented"?
> 
> Regards,
> 
> Simon
> 
> Mathias Brökelmann wrote:
>> the reason why I introduced this flag was a recent change to
>> t:datatable by martin who hard coded this to preserveRowState=true.
>> But it is not a solution for every one, since clearing the datamodel
>> cache and rowstate cache must be done together. If
>> preserveRowState=true is used only the datamodel cache is cleared
>> (which results in calling the getter method for the value of
>> t:datatable before rendering the response).
>>
>> If the rowstate is not cleared it is possible to save unbounded values
>> to the rendering phase. But if the datamodel changes (like add, remove
>> or sort rows) it will not work since t:datatable do not know which
>> rowstate belongs to which row data object. The rowstates are
>> identified only by the row index (current clientId of t:datatable is
>> used internally) not by row data.
>>
>> The rowstate and the datamodel must be held during decode, validate,
>> update and invoke application phases. before rendering the datatable
>> it is determined if an error in the previous phases happened. If that
>> is the case the rowstate and the datamodel cache is not cleared and
>> reused to show the error on the page with old content. If there is no
>> error the rowstate and datamodel cache is discarded.
>>
>> 2005/11/14, Grant Smith <wo...@gmail.com>:
>>> I'm having problems with this too. In my application, I now have to 
>>> submit
>>> twice before I see the changes effect the datatable, even though the 
>>> model
>>> is updated correctly after the first submit. I presume it's work in 
>>> progress
>>> :)
>>>
>>>
>>> On 11/13/05, Simon Kitching <sk...@obsidium.com> wrote:
>>>> Hi,
>>>>
>>>> I see that recently some work has been done on implementing a
>>>> "preserveRowStates" flag for the dataTable component.
>>>>
>>>> As is (now) documented, the ancestor UIData component uses the
>>>> "flyweight" pattern so that only one set of child objects is used to
>>>> represent the columns and their contents. As each row is selected via
>>>> setRowIndex, the component state is saved in _rowStates array, and the
>>>> components are reinitialised with the _rowStates entry appropriate for
>>>> the next row.
>>>>
>>>> However unless preserveRowState is set (it is false by default), the
>>>> encodeBegin method discards all row state before rendering begins.
>>>>
>>>> I'm puzzled by this. Why is the row state cleared?
>>>>
>>>> And if row state is going to be ignored, what's the point of saving it
>>>> at all?
>>>>
>>>> Regards,
>>>>
>>>> Simon
>>>>
>>>
>>>
>>> -- 
>>> Grant Smith
>>>
>>
>>
>> -- 
>> Mathias
>>
> 
> 


Re: dataTable: why are row states cleared before render?

Posted by Simon Kitching <sk...@obsidium.com>.
Thanks Mathias.

I now realise that (just like an InputText component will re-fetch its 
bound value before rendering) the UIData needs to re-fetch its DataModel 
object before rendering. And that when the datamodel object is reloaded 
the rowState really needs to be recomputed too, as the DataModel may 
have more elements, less elements, or reordered elements.

This is clearly inconvenient for people who want to set properties on 
the table's child components earlier in the processing, and those people 
can now set preserveRowState to true if they really need to do this. 
However the price they pay is that they must not ever change the order 
of objects in the DataModel.

In the case of controlling the "rendered" attribute for a particular 
component in a particular row (Grant Smith's case) it would presumably 
be better to ensure the child components have a value-binding which 
calculates the rendered attribute on demand rather than try to set 
rendered state in row components from some action listener method.

Have I got the above right?

Another question: I must be dense, but what's the reason that a UIData 
has a *map* of DataModel objects, keyed by the id of the UIData's parent 
component? Is this some special code to handle the case where a UIData 
component is "reparented"?

Regards,

Simon

Mathias Brökelmann wrote:
> the reason why I introduced this flag was a recent change to
> t:datatable by martin who hard coded this to preserveRowState=true.
> But it is not a solution for every one, since clearing the datamodel
> cache and rowstate cache must be done together. If
> preserveRowState=true is used only the datamodel cache is cleared
> (which results in calling the getter method for the value of
> t:datatable before rendering the response).
> 
> If the rowstate is not cleared it is possible to save unbounded values
> to the rendering phase. But if the datamodel changes (like add, remove
> or sort rows) it will not work since t:datatable do not know which
> rowstate belongs to which row data object. The rowstates are
> identified only by the row index (current clientId of t:datatable is
> used internally) not by row data.
> 
> The rowstate and the datamodel must be held during decode, validate,
> update and invoke application phases. before rendering the datatable
> it is determined if an error in the previous phases happened. If that
> is the case the rowstate and the datamodel cache is not cleared and
> reused to show the error on the page with old content. If there is no
> error the rowstate and datamodel cache is discarded.
> 
> 2005/11/14, Grant Smith <wo...@gmail.com>:
>> I'm having problems with this too. In my application, I now have to submit
>> twice before I see the changes effect the datatable, even though the model
>> is updated correctly after the first submit. I presume it's work in progress
>> :)
>>
>>
>> On 11/13/05, Simon Kitching <sk...@obsidium.com> wrote:
>>> Hi,
>>>
>>> I see that recently some work has been done on implementing a
>>> "preserveRowStates" flag for the dataTable component.
>>>
>>> As is (now) documented, the ancestor UIData component uses the
>>> "flyweight" pattern so that only one set of child objects is used to
>>> represent the columns and their contents. As each row is selected via
>>> setRowIndex, the component state is saved in _rowStates array, and the
>>> components are reinitialised with the _rowStates entry appropriate for
>>> the next row.
>>>
>>> However unless preserveRowState is set (it is false by default), the
>>> encodeBegin method discards all row state before rendering begins.
>>>
>>> I'm puzzled by this. Why is the row state cleared?
>>>
>>> And if row state is going to be ignored, what's the point of saving it
>>> at all?
>>>
>>> Regards,
>>>
>>> Simon
>>>
>>
>>
>> --
>> Grant Smith
>>
> 
> 
> --
> Mathias
> 


Re: dataTable: why are row states cleared before render?

Posted by Mathias Brökelmann <mb...@googlemail.com>.
the reason why I introduced this flag was a recent change to
t:datatable by martin who hard coded this to preserveRowState=true.
But it is not a solution for every one, since clearing the datamodel
cache and rowstate cache must be done together. If
preserveRowState=true is used only the datamodel cache is cleared
(which results in calling the getter method for the value of
t:datatable before rendering the response).

If the rowstate is not cleared it is possible to save unbounded values
to the rendering phase. But if the datamodel changes (like add, remove
or sort rows) it will not work since t:datatable do not know which
rowstate belongs to which row data object. The rowstates are
identified only by the row index (current clientId of t:datatable is
used internally) not by row data.

The rowstate and the datamodel must be held during decode, validate,
update and invoke application phases. before rendering the datatable
it is determined if an error in the previous phases happened. If that
is the case the rowstate and the datamodel cache is not cleared and
reused to show the error on the page with old content. If there is no
error the rowstate and datamodel cache is discarded.

2005/11/14, Grant Smith <wo...@gmail.com>:
> I'm having problems with this too. In my application, I now have to submit
> twice before I see the changes effect the datatable, even though the model
> is updated correctly after the first submit. I presume it's work in progress
> :)
>
>
> On 11/13/05, Simon Kitching <sk...@obsidium.com> wrote:
> > Hi,
> >
> > I see that recently some work has been done on implementing a
> > "preserveRowStates" flag for the dataTable component.
> >
> > As is (now) documented, the ancestor UIData component uses the
> > "flyweight" pattern so that only one set of child objects is used to
> > represent the columns and their contents. As each row is selected via
> > setRowIndex, the component state is saved in _rowStates array, and the
> > components are reinitialised with the _rowStates entry appropriate for
> > the next row.
> >
> > However unless preserveRowState is set (it is false by default), the
> > encodeBegin method discards all row state before rendering begins.
> >
> > I'm puzzled by this. Why is the row state cleared?
> >
> > And if row state is going to be ignored, what's the point of saving it
> > at all?
> >
> > Regards,
> >
> > Simon
> >
>
>
>
> --
> Grant Smith
>


--
Mathias

Re: dataTable: why are row states cleared before render?

Posted by Grant Smith <wo...@gmail.com>.
I'm having problems with this too. In my application, I now have to submit
twice before I see the changes effect the datatable, even though the model
is updated correctly after the first submit. I presume it's work in progress
:)

On 11/13/05, Simon Kitching <sk...@obsidium.com> wrote:
>
> Hi,
>
> I see that recently some work has been done on implementing a
> "preserveRowStates" flag for the dataTable component.
>
> As is (now) documented, the ancestor UIData component uses the
> "flyweight" pattern so that only one set of child objects is used to
> represent the columns and their contents. As each row is selected via
> setRowIndex, the component state is saved in _rowStates array, and the
> components are reinitialised with the _rowStates entry appropriate for
> the next row.
>
> However unless preserveRowState is set (it is false by default), the
> encodeBegin method discards all row state before rendering begins.
>
> I'm puzzled by this. Why is the row state cleared?
>
> And if row state is going to be ignored, what's the point of saving it
> at all?
>
> Regards,
>
> Simon
>



--
Grant Smith