Sylvain Wallez wrote:
Ben Pope wrote:

Sylvain Wallez wrote:

No, no identity at all! Since you replay the add/move/delete events, you just need to be able to remove/add items at specific positions. That means that the underlying collection should be a java.util.list or a dom Element.

But actually this can be even simpler and we don't need this record/replay thing :-)

Have a look at the dynamic template sample [1] and play with add/delete/move actions: each row has an ID which indicates the row's creation order. In the case of binding, we won't use exactly use this ID, but store in rows the position in the original collection as an attribute (e.g. "load-position").

When the repeater is saved, with this information it's easy to know where and how to bind its rows:
- if the "load-position" attribute exists, we bind to the corresponding object in the original collection,
- if the "load-position" attribute doesn't exist, that means the row is newly created, and we therefore create a new object to save it.


Row moves can be managed either by reordering the original collection or by creating a new collection to which objects will be added.

I like this more, and this has the potential to kill both the current (complicated) repeater binding and also the simple-repeater binding which becomes useless :-)

Sylvain

[1] http://localhost:8888/samples/blocks/forms/do-dynaRepeater.flow



What if the underlying structure can have different (previous) rows removed from it between when you load the model and save it back?


Obviously you would usually lock the back end model, but you should only need to lock the rows that you have retrieved, and deal with unique IDs in a common manner.

If you're just playing back positions and actions over the model, then you prevent simultaneous access to the data. Either that or you just push the complications into the users model.

I suppose you could just tag old rows as dead, instead of removing them. And then clean up when nothing is locked.

Having the identity solved this problem. Or have I missed something?



It all depends if you consider the repeater and the underlying collection to be part of the application data model or just a convenience container to show a set of independent objects to the user.


If it's a application-level collection, then the repeater should be considered just the same as finer-grained objects and locked as a whole, or checked for concurrent modification to prevent lost update if locking isn't an option.

With the identity mapping, as it is now, it's possible to select a subset of the children contained within a node:


<fruits>
   <fruit id="0">
      <name>Apple</name>
      <colour>green</colour>
   </fruit>
   <fruit id="1">
      <name>Orange</name>
      <colour>orange</colour>
   </fruit>
   <fruit id="2">
      <name>Mango</name>
      <colour>orange</colour>
   </fruit>

<fb:reapeater parent-path="fruits" row-path="fruit[colour='orange']" row-path-insert="fruit">

So now I can modify orange fruits without locking apple (or any other non-orange fruit). You could easily modify green fruit, as long as the id is being tracked.

If I start modifying orange fruit, then you start modifying green fruit by deleting apple, then I save the model back, obviously we have a problem as the positions are now off-by-one. So unless the replaying can take into account simultaneous accesses, all of the ones that happend since the form was loaded (what if using hibernate!), we've lost functionality.

If it's just a holder, then only individual rows are bound and saved to the underlying storage. Modified rows lead to an update and new rows lead to an insert. There is a problem though for deleted rows as the repeater does not track rows that have been deleted (and the corresponding IDs). But if the repeater is just a dumb container, deletion can occur as soon as the users triggers the delete action.

Does this answer your concerns, or did I missed something also?

I'm concerned that functionality has been lost - perhaps it's bad practice to bind directly to the back end model. Perhaps it should be discouraged in favour of having the user always deal with an intermediate layer which, for example, uses an identity. So surely by simplifying the repeater, you're just pushing the complicated identity stuff to the user?


I know that the repeater is a complicated beast as I've been trying to modify it for my own purposes. I'd love for there to be a much easier way of dealing with the binding, I just feel that using the identity is a very robust way of doing it and it's better to have it in the binding framework than the users code.

Thanks for your time,
Ben.

Reply via email to