WAComponent instances tree + proper page refreshing for user (back button) - confusion
I'm slightly confused about - how to properly refresh instantiated WAComponent tree and when.
In the Seaside manual says (About Callbacks):
"Do not change state while rendering... Just produce output and define callbacks that do the fancy stuff you can’t do while rendering."
OK, then my small example:
1) Suppose I have a page - WAMyListPage (WAComponent sub class), which presents a list of items from DB table, easy.
2) When WAMyListPage is instantiated at the beginnig, it loads 10 rows from the DB, creates WAMyItem (WAComponent subclass) for every DB row and puts these WAMyItem instances to the WAMyListPage instance variable "items" (OrderedCollection)
3) WAMyListPage is rendered to the browser (render call on all WAMyItem "items" components)
4) User 1 clisks on the WAMyItem component from the rendered list (on the WAMyListPage) and goes into item detail page (detail page is not interesting here)
5) User 2 deletes 5 items/rows from the database (some way)
6) User 1 clicks browser back button and returns to the WAMyListPage, two cases can occur:
A) typically, the "list page" is cached in the browser and browser immediatelly renders the list page from the cache - with all 10 old items (no refresh, broken old view with some non existing items)
B) request from the browser to the Seaside app is made again (with old Seaside URL from browser history), then Seaside app just renders old state of WAMyListPage instance from the history and again - there is all 10 old WAMyItem items instantiated, so, broken again, old items in the view
My question - where can I do a proper refresh of WAMyListPage list items? (manual refresh button in the Seaside app is unacceptable)
Note: I can solve this by reloading WAMyListPage "items" instvar collection in every renderContentOn: (reload from DB, reload all WAMyItem instances) + instruct the browser to not cache any web page (in HTTP headers), so in point (6A) above, browser will ignore caching and make request to Seaside app again.
In this way, everything works, WAMyListPage is actual every time, but main Seaside rule "Do not change state while rendering" is violated (WAMyItems are reinstantiated in every renderContentOn:).
Re: WAComponent instances tree + proper page refreshing for user (back button) - confusion
The problem you are describing is about concurrent changes to the datamodel and how you can keep the Seaside component state of concurrent sessions in sync.
First off, Seaside backtracking support is mostly intended for UI state and not model state.
Inevitably, the two are connected, as illustrated in your example of a list of items in a db where each data record corresponds to a UI component.
You can make changes to the component state in the action phase of a callback (e.g. in the callback attached to an anchor), however there is no way to refresh the state when the user uses the back button and deal with concurrent changes to the state.
An interesting similar discussion that proposes a way to avoid browser caching when the back button is used is described here: .
Next, I think there are a couple of options:
- Make sure the Seaside component state cannot be affected by concurrent changes. This means that you would not use separate components per record in your list. Instead, an entire list would be encapsulated in a single component and its rendering code directly uses the state of the data model rather than state stored in the UI.
- Fiddle around with the continuation restore code in WASnapshot and create separate WARenderPhaseContinuation classes for use in your application that restore the session state _and_ verify its consistency with the datamodel. You can do this cleanly as Seaside provides support to use your own continuation classes and thereby customize what needs to happen when restoring the session state. If you use the method to prevent caching described in , you can probably make something interesting with that.
This last option is an interesting one, but I don’t really have the time to dive into it to give it a try (though my fingers are iching ;)