Ondra Žižka
added a comment - 12/May/11 18:20 A note to http://apache-wicket.1842946.n4.nabble.com/Free-wicket-from-component-hierarchy-hell-tp3027705p3028177.html :
Perhaps hierarchy ambiguities could be solved by introducing a concept of "component tree path", e.g. instead of
add("form1").add("input");
add("form2").add("input")
we could have (while keeping backwards compatibility):
add("form1")
add("form1.input")
add("form2")
add("form2.input")
(Which might be what Juergen meant by "extending component resolution process".)
Pro: More flat code
Con: Less semantical code, performance drawback
I'm not really sure what would I prefer. But it would fit with PropertyModel.

Igor Vaynberg
added a comment - 12/May/11 18:28 there shouldnt be any ambiguities because all containers support queuing.
so if you have two components with the same id and you want to queue them both you have to queue them under a parent that will not cause ambiguities, eg
lets say you have
c1->input
c1->c2->input
the following code should obviously not work
queue(new Container("c1"));
queue(new Container("c2"));
queue(new Input("input"));
queue(new Input("input"));
because the page does not know how to resolve which input goes where, but - the following
Container c2;
queue(new Container("c1"));
queue(c2=new Container("c2"));
queue(new Input("input"));
c2.queue(new Input("input"));
should work because we have removed the ambiguity.

That would traverse this component's tree and return a collection of matching components.
Components could have CSS-like classes for this purpose.
Or with a collection proxy able to change the component...

Ondra Žižka
added a comment - 12/May/11 18:40 ..which leads me to another idea - jQuery-like components selectors:
getComponents("Form#form1 WebMarkupContainer.holder input"); // CSS-like syntax
That would traverse this component's tree and return a collection of matching components.
Components could have CSS-like classes for this purpose.
Or with a collection proxy able to change the component...
getComponents("Form#form1 WebMarkupContainer.holder input").setVisible(false)
Was something like that proposed?
Maybe this could bring some fresh air to solutions for things like group of checkboxes etc.

Igor Vaynberg
added a comment - 12/May/11 18:52 yes, something like this was proposed, but does not seem very useful. how often do you use a visitor to do something in wicket? which is what this is, a shorthand for visitors.

I assume:
queue(new Container("c1")); will immediately be executed because we don't need to wait for anything
queue(c2=new Container("c2")); same; invoke add() immediately
queue(new Input("input")); can be added to c1 or c2. Shall that request be stalled until later? Until when? Or shall it be added to the first occassion it finds (without a warning)?
c2.queue(new Input("input")); can be executed immediately without ambiguity. Should we retry the postponed entry now? In that case queue can only do add but no replace (IMO not a heavy limitation).

Juergen Donnerstag
added a comment - 22/Jun/11 15:29 What shall be the resolution logic in the example below
c1->input
c1->c2->input
Container c2;
queue(new Container("c1"));
queue(c2=new Container("c2"));
queue(new Input("input"));
c2.queue(new Input("input"));
I assume:
queue(new Container("c1")); will immediately be executed because we don't need to wait for anything
queue(c2=new Container("c2")); same; invoke add() immediately
queue(new Input("input")); can be added to c1 or c2. Shall that request be stalled until later? Until when? Or shall it be added to the first occassion it finds (without a warning)?
c2.queue(new Input("input")); can be executed immediately without ambiguity. Should we retry the postponed entry now? In that case queue can only do add but no replace (IMO not a heavy limitation).

its not exactly how it works. queue(new Container("c1")) will not be immediately executed, none of them will. unqueueing happens after/before? the initialization of the component when the markup is available.

when dequeuing we try to find a queued child closest to the container, so in the example above it will work like this:

resolving c1, found and dequeued
resolving c1->input. look in c1, not found. look in parent, found and dequeued
resolving c2. look in c1, not found. look in parent, found and dequeued
resolving c2->input: look in c2, found and dequeued

also i now think queue is too cumberson to type, we should probably rename it to "push"

Igor Vaynberg
added a comment - 22/Jun/11 16:03 its not exactly how it works. queue(new Container("c1")) will not be immediately executed, none of them will. unqueueing happens after/before? the initialization of the component when the markup is available.
when dequeuing we try to find a queued child closest to the container, so in the example above it will work like this:
resolving c1, found and dequeued
resolving c1->input. look in c1, not found. look in parent, found and dequeued
resolving c2. look in c1, not found. look in parent, found and dequeued
resolving c2->input: look in c2, found and dequeued
also i now think queue is too cumberson to type, we should probably rename it to "push"

Igor Vaynberg
added a comment - 09/Jul/11 21:39 @Juergen, right now your tests only test for rendering, but they should also test that before queued component's oninitialize is called the component is already a child of the correct parent.

@Igor not sure I understand. I thought that for all components (queued or not) onInitialize gets called in any case after it was added and it's markup is available. onInitialize will never be called for queued components while still waiting to be added. During unqueuing the component gets added and because it's markup is guaranteed to be available, onInitialize gets called. Did I misunderstand your question?

Juergen Donnerstag
added a comment - 10/Jul/11 07:44 @Igor not sure I understand. I thought that for all components (queued or not) onInitialize gets called in any case after it was added and it's markup is available. onInitialize will never be called for queued components while still waiting to be added. During unqueuing the component gets added and because it's markup is guaranteed to be available, onInitialize gets called. Did I misunderstand your question?

@Juergen
i simply stated that there should be tests that check the hierarchy in a queued component's oninitialize method. eg, to make sure oninitialize is not called on queue, but rather after dequeue.

Igor Vaynberg
added a comment - 10/Jul/11 07:48 @Juergen
i simply stated that there should be tests that check the hierarchy in a queued component's oninitialize method. eg, to make sure oninitialize is not called on queue, but rather after dequeue.

Igor Vaynberg
added a comment - 23/Mar/12 15:34 this is a much more complex problem that i thought initially, mainly because it has to work with auto resolved tags which "pollute" nesting information in markup.
some unfinished attempts at this are in the origin/sandbox/component-queueing and origin/sandbox/hierarchy-completion branches.

Martin Grigorov
added a comment - 23/Jan/14 16:09 Branch 'markup-driven-component-tree' contains alternative solution that is described at http://markmail.org/message/kx3ujbsi4p36je2t
It is not finished yet but any comments and use cases are welcome!
Diff against master can be seen at https://github.com/apache/wicket/compare/markup-driven-component-tree (Note: GitHub is a bit behind Apache Git!).