Re: WOComponent children
Re: WOComponent children
- Subject: Re: WOComponent children
- From: Chuck Hill <email@hidden>
- Date: Fri, 4 Jan 2008 21:14:39 -0800
On Jan 4, 2008, at 6:06 PM, Simon McLean wrote:
Hi Chuck -
Firstly, you should be proud of the code as it is - we use it in
stacks of places!
It may be useful, but it is not something that I will ever be proud
of. I am sure there is a better way to write it, I just need to see it.
But whilst on the topic of that findTabs code ...
The day before yesterday i spent several hours trying to re-work
the tab code in an attempt to get it to work by passing in an array
of dictionaries that defined what the tabs and content should be.
What was in the dictionaries? I wrote that for a fairly narrow
purpose. You may want to re-implement it.
But no joy. (note: i have no previous experience with
WODynamicElements so there was lots of "what the hell are
WOAssociations ??" :-))
The transient glue between a WOComponent, and a WODynamicElement.
Think of them as bindings that only have values in a specific context.
Correct me if i'm wrong, but the current code appears to generate
the tabs in AjaxTabPanel based on that template's children.
Yes, ugly isn't it?
So if you incorporate a WORepetition wrapped AjaxTabbedPanelTab it
all goes wrong because AjaxTabPanel only sees one
AjaxTabbedPanelTab with null values bound to it... eeek ... null
everything .. bail out.
Yes, that is exactly what happens. Tabs (as implemented) need to be
static.
However, if you create a set tabs statically the generated code
looks like it could be relatively easy to create in a set of
WOComponents (not that i have tried :-)).
I have not either.
So, my question is why use WODynamicElements rather than
WOComponents ?
That is a good question. Let me make up an answer. :-)
I usually use a WODynamicElement when I want more detailed access to
the bindings than I can get in a WOComponent. In the case of
AjaxTabbedPanel, I wanted to be able to easily get at the child
elements. Looking at the code, I suspect that I made
AjaxTabbedPanelTab a WODynamicElement mostly because that was the
mode I was thinking in and it was easier to do that than shift gears
into WOComponent land.
Chuck
On 5 Jan 2008, at 01:42, Chuck Hill wrote:
Caveat: I wrote that, but I am not proud of it. That is some
nasty code and I washed my hands after writing it. Twice.
I am working on a response to Aaron, but keep getting distracted.
Chuck
On Jan 4, 2008, at 3:17 PM, Simon McLean wrote:
I know you can do this in WODynamicElement. Here is an example
from Wonder's AjaxTabPanel:
private void findTabs(WODynamicGroup template) {
if (template == null) return;
NSArray children = template.childrenElements();
for (int i = 0; i < children.count(); i++) {
WOElement child = (WOElement)children.objectAtIndex(i);
if (child instanceof AjaxTabbedPanelTab) {
AjaxTabbedPanelTab childTab = (AjaxTabbedPanelTab)
child;
// The tabs need to have an id attribute so we
assign one if needed
if (childTab.id() == null) {
childTab.setId(new WOConstantValueAssociation
(id.valueInComponent(null) + "_pane_" + tabs.count()));
}
tabs.addObject(childTab);
}
else if (child instanceof WODynamicGroup) {
findTabs((WODynamicGroup)child);
}
}
}
On 4 Jan 2008, at 23:13, email@hidden wrote:
Hello,
How can I get the children of a WOComponent? More importantly,
all children and all descendants?
WOComponents seem to only know how to go up the tree (find their
parents).
If you ask a WOComponent for its template (which is roughly
its .html/.wod structure), you can then *almost* ask the
template to go down the tree for its children as WOComponents.
This is not straightforward because as far as I can tell, you
got to do a lot of "cursor incrementing" and tricky
instantiation of WOComponents. Not only do you have to deal with
the "template" but you must also consider a "_childTemplate" for
when you've got WOComponentContent and WOComponentReference
objects. I've got some code now that doesn't quite work because
on a complex page it gets the bindings confused when I try to
push a WOComponentReference into context.
I've asked a similar question about a day ago on the WOnder
list, but I've learned a bit more and realize it may be more
appropriate to ask the question here. So sorry if this appears
to be a bit of deja vu for those who read both lists but it's
actually a bit more than that. If you read the earlier message,
please disregard it as I believe this one is more meaningful.
Consider the following code snippet offered by Mr. Rentzsch:
http://www.wodeveloper.com/omniLists/webobjects-dev/2002/July/
msg00246.html
I got so excited when I saw this only to find out that this
example only works in the trivial case, when you don't have any
WOComponentContent such as a PageWrapper component. To make it
work in the general case appears to be very tricky and also
inefficient.
The reason why I'm doing this is because I'm trying to bootstrap
a phase into the request-response loop. In any given reuseable
subcomponent I'm designing, I want to be able to simply
implement "addRequiredWebResources(WOResponse, WOContext)".
Inside this method I would make calls that would examine the
HTML response content and insert multiple lines between the HTML
head tags. For example, CSS file resources and Javascript file
resources. This way I don't need monolithic CSS and JS files but
can break the files down and associate them with the reusable
components that need them. When a page is rendered to the user,
only the necessary JS and CSS resources are referred to in the
link and import statements of the head tag, automatically.
For this to work fully, appendToResponse() must go first so that
we have some "head" tags to discover. But before appendToResponse
() is done, it needs to call "addRequiredWebResources()" on
every possible subComponent in the tree... *every* one of them.
This means it needs to contact even those subComponents that are
inside of WOConditional containers that evaluated to false. So
yes, there would be many components whose "appendToResponse()"
was not called but "addRequiredWebResources()" was in fact called.
Before the world of partial page refreshes via AJAX and other
means, none of this mattered. But now, because I can refresh a
portion of the screen and show a previously missing "coolWidget"
subComponent that requires "coolLib.js" I'm in trouble. Problem
is, in a partial page refresh, there is no "head" tag so
"coolWidget" will fail horribly because "coolLib.js" is not
referenced between the head tags of the page. In a full page
refresh (before the Web 2.0 era) there is no problem because the
head tag is readily available. Get the picture?
I really need some advice here or a sample of how to get to all
the children and children's children of the outmost WOComponent.
Conceptually it would also be interesting to understand why
Apple only exposes the "parent" relationship of a WOComponent.
When you *really* think about it, it makes a lot of sense to get
to your children and not so much to get to the parent. Obviously
internally WebObjects knows how to get to the children,
otherwise appendToResponse won't work. You kind of need to know
how to get to the guys underneath you. Every time I think about
the "parent" relationship the usefulness of it smacks of
*clever*. Like maybe executing the action of a parent
WOComponent. But once you do something like that, you've heavily
tied the subComponent to the parent and it no longer becomes
reuseable. Think of a car tire. That tire should work no matter
what car I put it on. I should be able to pull it from one truck
and place it on another without a care in the world. If the tire
wants to let us know that its air pressure is low then it would
just shout "airPressureLow()" and the right components of the
car should be registered to listen to that message, so there is
no need to get to the "parent()".
I fear, without an adequate answer to the question of "how do I
get to my children", our beloved tool of choice can no longer
provide truely reusable WOComponents for the Web 2.0 era.
-- Aaron
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
email@hidden
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
40global-village.net
This email sent to email@hidden
--
Practical WebObjects - for developers who want to increase their
overall knowledge of WebObjects or who are trying to solve
specific problems.
http://www.global-village.net/products/practical_webobjects
--
Practical WebObjects - for developers who want to increase their
overall knowledge of WebObjects or who are trying to solve specific
problems.
http://www.global-village.net/products/practical_webobjects
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden