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
>

Reply via email to