You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by llama-king <p....@albourne.com> on 2013/01/14 14:03:29 UTC

Re: Elegant Handling of Multiple Zones in 'Deep' Hierarchies of Components

Reviving my old thread for continuity - just picking up the same train of
thought again. The theme, building some form of 'registry' for zones on a
given page. Either on a per session or environment basis; whatever is seen
to be most suitable.

The following example is for the sake of argument and we are making the
assumption that a suitably semantic situation has arisen where it is
entirely logical to want to update zones in this way.

Let's say we have this component structure:
<t:a>
    <t:b />
    <t:c>
      <t:d />
    </t:c>
</t:a>

All of these components declare one or more zones in their templates, need
to perform multiple zone updates per event and rely on each other in various
ways.

An event is triggered in d, it needs to update a zone in its parent
component c as well as in component b. So: d needs a reference to one of c's
zones and one of b's zones so as to either call
ajaxResponseRenderer.addRender(clientId, zone) or return the zone from the
event handler.

The current way we do this is by passing c's zone into d as a parameter. To
get at b's zone we have to create a getter for the zone in b, inject
component b in a, create a delegate getter for the zone in a, pass the zone
into c as a parameter and then pass the zone into d as a parameter.

The only nice thing about this whole process is in terms of refactoring, if
a zone is removed or renamed, we'll know about it via exception at render
time and won't push a broken site to production. :)

So I had a half-baked idea about having some sort of registry for zones;
- components register the injected instances of their zones, something like
Map<String, Zone> where string is ideally the zone's clientid.
- it will hold AjaxResponseRenderer.
- if a component needs to render a bunch of zones in a bunch of places, it
calls the registry's render method and supplies the string keys of the zones
that need to be updated.

The nasty thing about this is, if we remove or rename a registered zone,
we'd need to make sure we check all of the hierarchy of components for
references to rendering of that removed or renamed zone.

So I ask you fellow Tapestry people - any ideas what do?



--
View this message in context: http://tapestry.1045711.n5.nabble.com/Elegant-Handling-of-Multiple-Zones-in-Deep-Hierarchies-of-Components-tp5717698p5719297.html
Sent from the Tapestry - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Elegant Handling of Multiple Zones in 'Deep' Hierarchies of Components

Posted by llama-king <p....@albourne.com>.
Hi Geoff,

Many thanks for the response (and for jumpstart)! I went ahead and branched
and converted one of our component hierarchies to use bubbling where
appropriate.

Well bubbling does help to an extent, it definitely is an alternative to
passing zones as parameters and I can see how it's possible to rethink
component structure (mostly by wrapping zone around component rather than
the other way round) to achieve this in more scenarios.

It still doesn't feel too clean though, especially with a lot of bubbling
going on and components used in multiple places in multiple hierarchies of
components.

I guess I'm still wondering at whether there's still a cleaner way of
achieving this, somehow, lurking in someone's mind (even if it's not yet
implemented)!

Thanks again!



--
View this message in context: http://tapestry.1045711.n5.nabble.com/Elegant-Handling-of-Multiple-Zones-in-Deep-Hierarchies-of-Components-tp5717698p5719313.html
Sent from the Tapestry - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Elegant Handling of Multiple Zones in 'Deep' Hierarchies of Components

Posted by Geoff Callender <ge...@gmail.com>.
That response wasn't quite right - it was made too late at night. Of course, PersonList and PersonEditor do know they're in zones - the zone id is a parameter to each. Which has me wondering, have I addressed your issue at all?

On 15/01/2013, at 1:09 AM, Geoff Callender wrote:

> I meant:
> 
> 	http://jumpstart.doublenegative.com.au/jumpstart/together/gracefulajaxcomponentscrud/persons
> 
> Cheers,
> 
> Geoff
> 
> On 15/01/2013, at 12:31 AM, Geoff Callender wrote:
> 
>> I would recommend using event bubbling. Keep component d unaware of its container. It should bubble up an event and let c and a decide whether there is a zone they should refresh.
>> 
>> For an example of this philosophy have a look at 
>> 
>> 	http://localhost:8080/jumpstart/together/gracefulajaxcomponentscrud/persons . 
>> 
>> In it, PersonList and PersonEditor do not know about each other, nor do they know about their container, Persons, and nor do they know they are in zones. 
>> 
>> - When you modify PersonList's filter, it bubbles up event "filter" and the container does ajaxResponseRenderer.addRender(listZone);
>> - When you select one of PersonList's entries, it bubbles up "selected" and the container does ajaxResponseRenderer.addRender(listZone).addRender(editorZone);
>> 
>> Only Persons knows that there is a list and an editor, so it makes sense for it to coordinate the responses to the events.
>> 
>> In your case it will be a bit trickier if a zone inside b needs to be refreshed, but maybe you could move that zone up into a, around b? Nested zones would be tricky, too, but to date I've always been able to structure the components in a way that avoids them.
>> 
>> Cheers,
>> 
>> Geoff 
>> 
>> On 15/01/2013, at 12:03 AM, llama-king wrote:
>> 
>>> Reviving my old thread for continuity - just picking up the same train of
>>> thought again. The theme, building some form of 'registry' for zones on a
>>> given page. Either on a per session or environment basis; whatever is seen
>>> to be most suitable.
>>> 
>>> The following example is for the sake of argument and we are making the
>>> assumption that a suitably semantic situation has arisen where it is
>>> entirely logical to want to update zones in this way.
>>> 
>>> Let's say we have this component structure:
>>> <t:a>
>>>    <t:b />
>>>    <t:c>
>>>      <t:d />
>>>    </t:c>
>>> </t:a>
>>> 
>>> All of these components declare one or more zones in their templates, need
>>> to perform multiple zone updates per event and rely on each other in various
>>> ways.
>>> 
>>> An event is triggered in d, it needs to update a zone in its parent
>>> component c as well as in component b. So: d needs a reference to one of c's
>>> zones and one of b's zones so as to either call
>>> ajaxResponseRenderer.addRender(clientId, zone) or return the zone from the
>>> event handler.
>>> 
>>> The current way we do this is by passing c's zone into d as a parameter. To
>>> get at b's zone we have to create a getter for the zone in b, inject
>>> component b in a, create a delegate getter for the zone in a, pass the zone
>>> into c as a parameter and then pass the zone into d as a parameter.
>>> 
>>> The only nice thing about this whole process is in terms of refactoring, if
>>> a zone is removed or renamed, we'll know about it via exception at render
>>> time and won't push a broken site to production. :)
>>> 
>>> So I had a half-baked idea about having some sort of registry for zones;
>>> - components register the injected instances of their zones, something like
>>> Map<String, Zone> where string is ideally the zone's clientid.
>>> - it will hold AjaxResponseRenderer.
>>> - if a component needs to render a bunch of zones in a bunch of places, it
>>> calls the registry's render method and supplies the string keys of the zones
>>> that need to be updated.
>>> 
>>> The nasty thing about this is, if we remove or rename a registered zone,
>>> we'd need to make sure we check all of the hierarchy of components for
>>> references to rendering of that removed or renamed zone.
>>> 
>>> So I ask you fellow Tapestry people - any ideas what do?
>>> 
>>> 
>>> 
>>> --
>>> View this message in context: http://tapestry.1045711.n5.nabble.com/Elegant-Handling-of-Multiple-Zones-in-Deep-Hierarchies-of-Components-tp5717698p5719297.html
>>> Sent from the Tapestry - User mailing list archive at Nabble.com.
>>> 
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>> 
>> 
> 


Re: Elegant Handling of Multiple Zones in 'Deep' Hierarchies of Components

Posted by Geoff Callender <ge...@gmail.com>.
I meant:

	http://jumpstart.doublenegative.com.au/jumpstart/together/gracefulajaxcomponentscrud/persons

Cheers,

Geoff

On 15/01/2013, at 12:31 AM, Geoff Callender wrote:

> I would recommend using event bubbling. Keep component d unaware of its container. It should bubble up an event and let c and a decide whether there is a zone they should refresh.
> 
> For an example of this philosophy have a look at 
> 
> 	http://localhost:8080/jumpstart/together/gracefulajaxcomponentscrud/persons . 
> 
> In it, PersonList and PersonEditor do not know about each other, nor do they know about their container, Persons, and nor do they know they are in zones. 
> 
> - When you modify PersonList's filter, it bubbles up event "filter" and the container does ajaxResponseRenderer.addRender(listZone);
> - When you select one of PersonList's entries, it bubbles up "selected" and the container does ajaxResponseRenderer.addRender(listZone).addRender(editorZone);
> 
> Only Persons knows that there is a list and an editor, so it makes sense for it to coordinate the responses to the events.
> 
> In your case it will be a bit trickier if a zone inside b needs to be refreshed, but maybe you could move that zone up into a, around b? Nested zones would be tricky, too, but to date I've always been able to structure the components in a way that avoids them.
> 
> Cheers,
> 
> Geoff 
> 
> On 15/01/2013, at 12:03 AM, llama-king wrote:
> 
>> Reviving my old thread for continuity - just picking up the same train of
>> thought again. The theme, building some form of 'registry' for zones on a
>> given page. Either on a per session or environment basis; whatever is seen
>> to be most suitable.
>> 
>> The following example is for the sake of argument and we are making the
>> assumption that a suitably semantic situation has arisen where it is
>> entirely logical to want to update zones in this way.
>> 
>> Let's say we have this component structure:
>> <t:a>
>>    <t:b />
>>    <t:c>
>>      <t:d />
>>    </t:c>
>> </t:a>
>> 
>> All of these components declare one or more zones in their templates, need
>> to perform multiple zone updates per event and rely on each other in various
>> ways.
>> 
>> An event is triggered in d, it needs to update a zone in its parent
>> component c as well as in component b. So: d needs a reference to one of c's
>> zones and one of b's zones so as to either call
>> ajaxResponseRenderer.addRender(clientId, zone) or return the zone from the
>> event handler.
>> 
>> The current way we do this is by passing c's zone into d as a parameter. To
>> get at b's zone we have to create a getter for the zone in b, inject
>> component b in a, create a delegate getter for the zone in a, pass the zone
>> into c as a parameter and then pass the zone into d as a parameter.
>> 
>> The only nice thing about this whole process is in terms of refactoring, if
>> a zone is removed or renamed, we'll know about it via exception at render
>> time and won't push a broken site to production. :)
>> 
>> So I had a half-baked idea about having some sort of registry for zones;
>> - components register the injected instances of their zones, something like
>> Map<String, Zone> where string is ideally the zone's clientid.
>> - it will hold AjaxResponseRenderer.
>> - if a component needs to render a bunch of zones in a bunch of places, it
>> calls the registry's render method and supplies the string keys of the zones
>> that need to be updated.
>> 
>> The nasty thing about this is, if we remove or rename a registered zone,
>> we'd need to make sure we check all of the hierarchy of components for
>> references to rendering of that removed or renamed zone.
>> 
>> So I ask you fellow Tapestry people - any ideas what do?
>> 
>> 
>> 
>> --
>> View this message in context: http://tapestry.1045711.n5.nabble.com/Elegant-Handling-of-Multiple-Zones-in-Deep-Hierarchies-of-Components-tp5717698p5719297.html
>> Sent from the Tapestry - User mailing list archive at Nabble.com.
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>> 
> 


Re: Elegant Handling of Multiple Zones in 'Deep' Hierarchies of Components

Posted by Geoff Callender <ge...@gmail.com>.
I would recommend using event bubbling. Keep component d unaware of its container. It should bubble up an event and let c and a decide whether there is a zone they should refresh.

For an example of this philosophy have a look at 

	http://localhost:8080/jumpstart/together/gracefulajaxcomponentscrud/persons . 

In it, PersonList and PersonEditor do not know about each other, nor do they know about their container, Persons, and nor do they know they are in zones. 

- When you modify PersonList's filter, it bubbles up event "filter" and the container does ajaxResponseRenderer.addRender(listZone);
- When you select one of PersonList's entries, it bubbles up "selected" and the container does ajaxResponseRenderer.addRender(listZone).addRender(editorZone);

Only Persons knows that there is a list and an editor, so it makes sense for it to coordinate the responses to the events.

In your case it will be a bit trickier if a zone inside b needs to be refreshed, but maybe you could move that zone up into a, around b? Nested zones would be tricky, too, but to date I've always been able to structure the components in a way that avoids them.

Cheers,

Geoff 

On 15/01/2013, at 12:03 AM, llama-king wrote:

> Reviving my old thread for continuity - just picking up the same train of
> thought again. The theme, building some form of 'registry' for zones on a
> given page. Either on a per session or environment basis; whatever is seen
> to be most suitable.
> 
> The following example is for the sake of argument and we are making the
> assumption that a suitably semantic situation has arisen where it is
> entirely logical to want to update zones in this way.
> 
> Let's say we have this component structure:
> <t:a>
>    <t:b />
>    <t:c>
>      <t:d />
>    </t:c>
> </t:a>
> 
> All of these components declare one or more zones in their templates, need
> to perform multiple zone updates per event and rely on each other in various
> ways.
> 
> An event is triggered in d, it needs to update a zone in its parent
> component c as well as in component b. So: d needs a reference to one of c's
> zones and one of b's zones so as to either call
> ajaxResponseRenderer.addRender(clientId, zone) or return the zone from the
> event handler.
> 
> The current way we do this is by passing c's zone into d as a parameter. To
> get at b's zone we have to create a getter for the zone in b, inject
> component b in a, create a delegate getter for the zone in a, pass the zone
> into c as a parameter and then pass the zone into d as a parameter.
> 
> The only nice thing about this whole process is in terms of refactoring, if
> a zone is removed or renamed, we'll know about it via exception at render
> time and won't push a broken site to production. :)
> 
> So I had a half-baked idea about having some sort of registry for zones;
> - components register the injected instances of their zones, something like
> Map<String, Zone> where string is ideally the zone's clientid.
> - it will hold AjaxResponseRenderer.
> - if a component needs to render a bunch of zones in a bunch of places, it
> calls the registry's render method and supplies the string keys of the zones
> that need to be updated.
> 
> The nasty thing about this is, if we remove or rename a registered zone,
> we'd need to make sure we check all of the hierarchy of components for
> references to rendering of that removed or renamed zone.
> 
> So I ask you fellow Tapestry people - any ideas what do?
> 
> 
> 
> --
> View this message in context: http://tapestry.1045711.n5.nabble.com/Elegant-Handling-of-Multiple-Zones-in-Deep-Hierarchies-of-Components-tp5717698p5719297.html
> Sent from the Tapestry - User mailing list archive at Nabble.com.
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>