Well, this is kinda odd.
I've implemented the converter version, and it *almost* works.
Without the converter, using the standard clientId key,
public String getAsString(FacesContext context, UIComponent
component, Object value)
{
UIData uiData = (UIData)component;
return uiData.getClientId(context);
}
If you have
row 1 - 1111
row 2 - 2222
row 3 - 3333
row 4 - 4444
row 5 - 5555
and you delete row 2, you get:
row 1 - 1111
row 3 - 2222
row 4 - 3333
row 5 - 4444
Now if I throw in a converter that maps to an object:
public String getAsString(FacesContext context, UIComponent
component, Object value)
{
UIData uiData = (UIData)component;
if (uiData.isRowAvailable())
{
Item item = (Item)uiData.getRowData();
return "Item" + String.valueOf(item.getId());
}
return uiData.getClientId(context);
}
If you have
row 1 - 1111
row 2 - 2222
row 3 - 3333
row 4 - 4444
row 5 - 5555
and you delete row 2, you get:
row 1 - 1111
row 3 - 2222
row 4 - 4444
row 5 - 5555
Weird. Everything is correct except for row 3 (which picked up the
values for row 2), which is a vast improvement over the original, but
still not quite right.
On 4/11/07, Mike Kienenberger <[EMAIL PROTECTED]> wrote:
I don't think this will affect the nested datatables since we're not
changing the value, only the key, for each row-state map entry.
However, I might be misunderstanding something.
A starting point could be
private Map _rowStates = new WeakHashMap();
Then, we'd change this:
_rowStates.put(getClientId(facesContext),
saveDescendantComponentStates(getChildren()
.iterator(), false));
to
_rowStates.put(dataModel.getRowData(),
saveDescendantComponentStates(getChildren()
.iterator(), false));
Note, for describing this, I'm ignoring how we'd handle isRowAvailable=false.
I'm guessing this would require that rowData be serializable.
A better implementation might be:
Converter converter = .... [either assigned explicitly or
fetched by RowData type]
_rowStates.put(converter.getAsString(dataModel.getRowData()),
saveDescendantComponentStates(getChildren()
.iterator(), false));
Now we're no longer storing a weak reference to the model object
(good), but we'll now have to be responsible for keeping the
_rowStates map cleaned up (bad). Now we won't have serialization
issues (good).
One potential snag might be if the backing data model contains
identical objects. I can't think of a practical use case for this
(inputs on multiple rows for the same object), but that doesn't mean
that there isn't one.
On 4/11/07, Martin Marinschek <[EMAIL PROTECTED]> wrote:
> Your ideas sound good, one thing that I remember was discussed while
> implementing preserveRowStates - there were some problems with nested
> data-tables - you'd need to work around those problems specifically.
>
> What would be your idea of a key based on the row-data?
>
> regards,
>
> Martin
>
> On 4/11/07, Mike Kienenberger <[EMAIL PROTECTED]> wrote:
> > I'm looking into the behavior of preserveRowStates in order to try to
> > fix the issues with deleting a row when preserveRowStates=true.
> >
> > One of the things I notice is that the key to the row state Map is the
> > clientid of the dataTable, which of course varies based on the row
> > index. Is there some reason why the key isn't the row index?
> >
> > What about the possibility of storing the row data in the map using a
> > key based on the row data itself? That way, changing the row model
> > (adding/deleting rows) would automatically pick the right row state?
> > The only issues are that we might be keeping the row state for rows
> > that no longer in the model, and we might be holding onto a reference
> > to an object that should be garbage collected (I've never delved into
> > this, but my understanding is that there are ways around referencing
> > things that should perhaps be garbage-collected).
> >
> > However, if it works, it would automaticallly solve all of the row
> > issues transparently to the end-user. Sorting, inserting, deleting
> > rows would work transparently.
> >
> > We might also want to put in a preserveRowStatesConverter so we save a
> > light-weight key to the row data rather than the row data itself like
> > f:selectItems does.
> >
>
>
> --
>
> http://www.irian.at
>
> Your JSF powerhouse -
> JSF Consulting, Development and
> Courses in English and German
>
> Professional Support for Apache MyFaces
>