[Seaside] Re: Menu component - communicating with root component

Holger Kleinsorgen kleinsor at smallish.org
Sun Apr 20 19:10:14 UTC 2008


>> So... where is this announcer, how does bodyB obtain its 
>> announcer? If there is one global announcer, then what routes 
>> a ReloadBody to the Correct BodyA or B.
> 
> OK, consider this, in Seaside, all components answer #children, so all
> parents have access to their children.  The ChangeBody announcement could be
> fired like this...

> self session announce: (ChangeBody sender: self with: [:body | body call:
> BlaBla new])
> Now, both parent components catch the event, check to make sure the #sender
> is one of their children or grandchildren with a quick recursive check on
> #children, before deciding to process the announcement.  This way you scope
> the ChangeBody to the correct parent.

Peeking at grandchildren is IMHO even worse than accessing a parent. 
It's the same princicple (traversing the component hierarchy), just more 
laborious.

>> So menuItemB, performs "self announce: (anAnnouncement)" on 
>> an announcer.
>>
>> ok... where is this announcer? How does it know about it?
> 
> Put it on the session and then every component has access to a single global
> announcer.

Using the session as global variable dump and central router for 
application logic isn't very auspicious, too.

I faced a similiar problem recently, and initially used the 
give-components-its-parent-but-only-use-it-for-announcing-approach. 
however, it was doomed once I had to announce events between siblings.

Subscribing each and every component with potentially a lot of other 
components didn't look very promising, too.

For instance, in VisualWorks, window events are sometimes dispatched in 
both directions. First down, then up, with multiple interested parties 
in the middle. It's hard to follow, and often fails as soon as the 
hierarchy differs from the expected structure.

I finally ended up using an "environment" object, that holds some shared 
data (selection etc.) and also acts as an announcer. Parent components 
create it and pass it to their children. Children, when creating 
grand-children, may decide to either pass the environment object to them 
or create a new one.

In the example, there would be two such objects (one for A, one for B). 
Let's call them EnvironmentA and EnvironmentB.

ParentA is subscribed to EnvironmentA. And for the menu flashing, MenuA 
is subscribed to EnvironmentA, too (however, MenuA doesnt exactly know 
that it is the EnvironmentA, for MenuA it's just "an Environment").

page reload goes like this:

   MenuItem>>triggerReload
      self environment announce: (Reload page: ...)

menu flashing

   MenuItem>>flash
      self envronment announce: (Flash ...)

and to make it work:

    Menu>>initialize
      self environment when: Flash do: [ : gordon | self flash: gordon ]

    Parent>>initialize
      self environment when: Reload do: [ : page | self call: page ].

the advantage of this approach is, that it won't break when you leave 
the strictly hierarchical approach. And you don't need a central router. 
And you don't break encapsulation rules.



More information about the seaside mailing list