Hi,

I still find it confusing :-/

1) with this we will have: the constructor, onInitialize() and
onAddToPage() being called as component initializers. Way too much IMO.
onInitialize() and onAddToPage() are exactly the same thing at this stage.

2) onRemove() is not named onRemoveFromPage(). (I don't like the name
onAddToPage())

Is it possible to redo it as onReAdd(), i.e. it will be called when the
component is added to a parent and it is already initialized. Not sure but
maybe all that is needed to do it is to remove the call to onAddToPage() in
onInitialize(), and rename the method.

My 2c.


Martin Grigorov
Wicket Training and Consulting
https://twitter.com/mtgrigorov


On Mon, Aug 18, 2014 at 11:29 AM, Carl-Eric Menzel <[email protected]>
wrote:

> Hi everybody,
>
> I am currently dealing with
> https://issues.apache.org/jira/browse/WICKET-5265:
>
> A FencedFeedbackPanel marks the component it uses as a fence with a
> metadata entry, so that outer FencedFeedbackPanels do not traverse
> beyond that component to "steal" feedback messages. When an FFP is
> removed from the hierarchy (either by itself or as part of a subtree
> that is being removed), onRemove is called on it (and on all other
> components of that subtree). In onRemove, the FFP removes the fence
> mark. So far, so correct.
>
> When the FFP is added back to the page, there is no corresponding
> lifecycle callback that would tell it about the fact that it has been
> added back, so it cannot recreate the fence mark. This leads to outer
> FFPs stealing the messages.
>
> This "adding the same component back" is not a rare operation: It is
> for example what the Wizard component does with its WizardStep panels.
> They get removed and added all the time.
>
> I tried working around this by using onConfigure and/or onBeforeRender.
> In the really simple cases that works, but there can be more
> complicated component hierarchies. Even in a simple wizard the way
> Wicket traverses the tree and calls these two events can't guarantee
> that the inner FFP's onConfigure is called before the outer FFP tries
> to get the messages.
>
> I have uploaded a quickstart to the WICKET-5265 ticket to demonstrate
> this.
>
> Using a filter to prevent already rendered messages from being rendered
> again does not help, because then it is only the outer panel that shows
> them, not the inner one where they should be.
>
> martin-g suggested using onInitialize, but that does not work.
> onInitialize is called only once over the entire lifetime of the
> component, when it is first added to a page, and never again. It
> doesn't matter whether one sees it as basically a delayed constructor
> that allows calling overridden subclass methods, or as an indication of
> "hey, your page is here for the first time". The problem is that it is
> by definition only called once. The remove-and-add situation is not
> covered.
>
> onRemove is called every time a component (or a parent) is removed from
> the page hierarchy, so components can clean up after themselves.
>
> I think that just like behaviors have bind() and unbind(), components
> should have a kind of onAdd() to complement onRemove(). I have an
> implementation for this that is tested and works. With this, the
> problem described above can be elegantly solved.
>
> I named the method onAddToPage to make it more clear when it will be
> called and to reduce the chance for a name collision.
>
> I have defined it as follows:
> onAddToPage is called whenever a component is added to a parent in a
> way that connects it to the Page instance, but not before onInitialize
> has been called.
>
> For example:
>  - a component gets added to the page after it is constructed
>    1. onInitialize
>    2. onAddToPage
>
>  - a component is removed from the page and then added again
>    1. onAddToPage
>
>  - a component is added to a container that is already added to the page
>    1. onInitialize (if necessary)
>    2. onAddToPage
>
>  - a component is added to a container that is *not yet* added to the
>    page
>    1. nothing is called!
>    When the container is added to the page, its onAddToPage is called,
>    and recursively for all its children, just like all the other
>    lifecycle events.
>
> I think this is quite well-defined. martin-g commented there might be
> confusion with onInitialize.
>
> The javadoc of onInitialize says:
>
> > This method is meant to be used as an alternative to initialize
> > components. Usually the component's constructor is used for this task,
> > but sometimes a component cannot be initialized in isolation, it may
> > need to access its parent component or its markup in order to fully
> > initialize. This method is invoked once per component's lifecycle
> > when a path exists from this component to the {@link Page} thus
> > providing the component with an atomic callback
> > when the component's environment is built out.
>
> This is reasonably well-defined, though it completely ignores the fact
> that onRemove might happen. Also, it only says that onInitialize will
> be called "sometime before Component#onBeforeRender()" which I think is
> more confusing than anything else. It should probably be changed to
> "just before onConfigure".
>
> I propose this for documentation of onAddToPage:
>
> /**
>  * This method is called whenever a component is added to the component
>  * tree connected to the page,
>  * to allow it to initialize things that depend on other
>  * components in the page. This is similar
>  * to {@link #onInitialize()}. However, onInitialize is only
>  * ever called once, the first time the
>  * component is added. It is not called when a component is
>  * removed and then added again.
>  *
>  * This method, however, is called every time the component is
>  * added to the page's tree. It is
>  * never called before onInitialize(). It is thus the opposite
>  * of onRemove().
>  *
>  * Subclasses that override this must call super.onAddToPage().
>  */
>
> I think the important point here is that it is the opposite of
> onRemove, and is meant to complement it.
>
> I've created https://issues.apache.org/jira/browse/WICKET-5677 for this
> and have pushed my implementation to the branch WICKET-5677.
>
> What do you think?
>
> Carl-Eric
>

Reply via email to