On 24/09/2014 16:22, Garret Wilson wrote:
On 9/24/2014 9:26 AM, Martijn Dashorst wrote:
On Wed, Sep 24, 2014 at 2:13 AM, Garret Wilson <gar...@globalmentor.com> wrote:
I'm not denying that versioned pages may be a useful concept for some use
cases (even though I can't think of any offhand).
Persioning is a very useful concept and used in many applications. You
are just focussing on your particular use case for today and not
thinking of broader issues that we have tackled for about a decade.

Take google's search page with the pagination at the bottom. Click on
2, click on back. What do you expect? go back to the page before you
searched google? Or go back to page 1?



But note that in your example you're not talking about the "version of the page". You're pointing to a /navigation control/, which of course I would expect to interact with navigation. Notice that when you page back and forth, you actually change the URL query (e.g. start=10). So you're not changing the "version" of the page---you're actually modifying the query you send to the page, and of course you can navigate among different page queries. In fact Wicket already has a totally separate mechanism for sending queries to pages through page parameters, exactly like Google is doing.

I am completely in favor of sending page query parameters in the URL when I want to specify what data should be retrieved from a query, and for the user to navigate among queries. But I still (in my use case) don't have a need for that same query page to be "versioned".

Hi Garret,

(Side note: you probably should not be overriding isVisible(). Call setVisibilityAllowed() in onConfigure(). isVisible() is often called multiple times during a request cycle and, if expensive, can lead to some slowness.)

Page classes are mounted at a specific URL, not page instances. A page instance is made up of a component tree as well as page state - data stored in the component tree. When you request a mounted URL, you get a new page instance as created from that mounted page class. That is the basic contract of the mount. Serving up anything other than this would be incorrect, as it breaks the contract.

Humor me here. Please think of the page instance strictly as component tree and page state. Think of the page class as a starting point, a factory. If you create a new object from the class, you get a specific page instance (again, think component tree and page state).

Now, if the page state or component tree changes, the page instance is no longer "that thing you would get if you created a new instance of that page class". It is a different beast now. The fact that this Wicket has no business serving up this beast when the user requested the mounted URL, aka "that thing you would get if you created a new instance of that page class".

Every time the component tree or page state changes, it is no longer the same page. Because it is no longer the same page, the URL changes. This is where is helps to think of a page as a component tree and page state. Its not so much different versions of the same page, as much as different pages.

I'd like to point specifically to the impact of page state here. Being able to record state in the page object is one of the things that makes Wicket awesome, but it is not the only place to store state. You can also store state in the session, in a database, and in cookie, query and post parameters.

When Wicket talks about stateful pages, its talking about component tree and page state (the state stored in the component tree - the Page object being the root of the component tree). A Wicket page is stateful when it does, or could, change the component tree or PAGE state. When a page does not modify the PAGE state, then it is stateless in Wicket language (excuse the simplification).

Using stateless pages reading and writing state outside of the page object can get you most, if not all, of what you want.

Lets take your Facebook example:

1. "Each time you go to https://www.facebook.com/jdoe, it would
   redirect you to https://www.facebook.com/jdoe?1";. Not if it was a
   stateless page.
2. "Imagine if you clicked "Like" on somebody's picture, and it
   redirectred you to https://www.facebook.com/jdoe?3";. Again, not if
   it was a stateless page. Why should clicking "Like" change the page
   state or the component tree? In other words, why does this need to
   be a stateful link, why not use a StatelessLink? All the data of who
   likes what is not stored in PAGE state. It is stored in a database.
3. "But it still kept https://www.facebook.com/jdoe?2 in memory, so
   that when you hit "Back" you'd see the picture before you liked
   it.". Again, stateless pages are not stored in the page store, so
   you would have a /jdoe?2 in memory. Also, whether or not you like a
   picture should not be pulled from page state, but from a database or
   cache somewhere. The page runs onConfigure each time before
   rendering, so you would highlight the little thumbs up on the next
   render if the value in the database now indicates that the picture
   is liked.
4. "So you're saying that if I'm careful to use all dynamic models
   (even overriding isVisible() for components to dynamically query
   whether they should be visible), then my web application will wind
   up with many versions of the same page serialized on disk somewhere,
   all with different URL queries, and the user can navigate among
   them, but when rendered they will all show 100% the same data?" With
   a stateless page, you would have no copies serialized. A new page
   would be created each time. No navigating between different copies.
   Each time the URL is requested, a new instance is created to display
   the backing data, whatever that may be at the time.

To take your Google example, the state is being managed in the query parameters, not the page state. You dont need stateful pages here either. You can use stateless, bookmarkable links.

Your initial use case of having a staging page which should look the same for all requests in that session. Would it not make sense to store the data in the session, use a stateless page to manipulate and display the data stored in the session?

Cheers,
Jesse

Reply via email to