[Seaside] Menu component - communicating with root component

Keith Hodges keith_hodges at yahoo.co.uk
Sat Apr 19 17:25:00 UTC 2008


Edward Stow wrote:
> On Sat, Apr 19, 2008 at 6:41 PM, Philippe Marschall
> <philippe.marschall at gmail.com> wrote:
>   
>> http://onsmalltalk.com/programming/smalltalk/maintaining-loose-coupling-in-seaside-components/
>>
>>     
> Thanks -- that confirms my approach as being ok.  Perhaps its a good
> time to brush up on announcements.
>   
I keep coming up against this one, AND I have to figure it out by next 
Thursday. Last time I said this I hacked a workaround instead.

Essentially seaside is architected so that for components, children do 
not know their parents. The rationale for this is that it enables 
children to be more reusable if there are no explicit interfaces to 
their containers.

However I have always found it essential to have children be able to 
"look around" and know their position in the world. After a year of 
using seaside and pier seriously, I have constantly had to find 
work-arounds, for what I know should be really simple.

My workarounds are not particularly elegant, and the code has smelt bad 
from the beginning. They have involved using some form of global as a 
holder for information that a child and a parent want to share.

Example 1)

In my pier-shop the WACurrentSession or the PRCurrentContext ends up 
holding the "current product being viewed", and all the components look 
to the current context as a kind of "global" data structure as to what 
to display. This has significant limitations, since you cannot have more 
than one current product at a time, and it violates the whole 
component-encapsulation model.

I implemented an Announcements helper in Seaside28Jetsam, which simply 
makes an instance of Announcer available via "WACurrentSession 
announcer". This appears to me to be a more complex and flexible form of 
the "put the communication in a global place, so parents and children 
can communicate"

What I want to do is to click on a product and have that call: the 
product display, which is a pier page, a template which has been 
assembled out of content and components, giving the pier page the 
current product, or the current users cart-model as a property, and have 
the child components be able to query the parents as to what product to 
display.

This would allow an administrator to have a side by side view of all the 
current carts of the currently logged in users. The cart displays would 
be generic container components, pier pages, with specialised children 
components, and the users' carts-models would be a property of outer 
page of each individual cart display. The inner cart display components 
would need to be able to query their containers as to what is in their 
cart that is to be displayed. This then allows components to be more 
granular, e.g. "Total cost" component, which could appear anywhere in 
the template. In contrast to the monolthic, Cart display, with tax 
calulations, and totals etc... component.

Example 2) (a simpler one)

In migrating a complex Magritte form to use Magritte-scriptaculous, I 
successfully wire up the models so that a change in one select drop 
down, changes items in other fields in the same form. The child field 
which has changed needs to trigger its form, so that all of changes in 
all of the the relevant fields are received by the model, and then 
scriptaculous update rendering, of not just its own component, but one 
of its parents (at some level). Since it is the components onChanged: 
event and callback: which is triggered when the user has changed the 
select box, it is the component which needs to trigger the form and the 
update.  But as per usual, the inner component has no means for 
dynamically discovering "what is the form id that I am in", or asking 
the relevant parent to update.

Solution Background
----------------------------

I have modelled complex physical assemblies before. The case that comes 
to mind was that of physical telecomunications equipment, where a card 
gets put in a slot or pulled out of a slot. Some cards specifically 
handle the alarms generated by all of the cards in their part of the 
rack, and they also translate the physical events into alarms which are 
sent up to the management interface.

The important concept I adopted in modelling physical heirarchies, was 
to allow the actual structure to influence behaviour. For example a lone 
card generating an alarm, would have no effect on the rest of the system 
if it is not physically plugged in.

To achieve this, I always had the child know its parent. But, in keeping 
with the loose-coupling principle I did not have any hard wired interface.

Instead I had an announcements like approach, called a SemanticMessage. 
A SemanticMessage when triggered would walk up the hierarchy, calling 
#smParent on each component and if it found either...

a) someone able to respond to the message, the message would be sent and 
the response value returned to the triggerer.
b) someone who had registered an interest in the message at some point 
in the hierarchy.

The Alarm card is sent a #cardInserted:intoSlot: SemanticMessage by the 
rack, it responds to this by registering an interest in any alarm events 
which arrive at the rack, from any card. Alarm events migrate up the 
heirarchy from the source card to the rack where the dependant is informed.

--

I present this in an effort to dispel what I believe is a myth, that 
children should not have any explicit knowledge their parents. I am sure 
enough to say that it is essential that this knowledge be there, the 
child should have a direct instVar (or property) to its parent. What is 
more important is how you use that instVar. Direct usage of the parents 
interface creates the inflexibility that we are trying to avoid.

So out use of the #parent instVar should be event or query based, rather 
than being a direct use of the parents interface. e.g. A child can 
trigger "I have Changed", and it is up to the parent to respond 
appropriately. Or a child can seek information #lookupContainingFormId, 
as long as it can handle the case that a heirarchy of parent which 
doesnt contain a form may not respond appropriately.

I am really looking forward to solving this one

best regards

Keith





More information about the seaside mailing list