tapestry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Balázs Palcsó <palcso.bal...@gmail.com>
Subject Re: Refreshing zone in layout triggered by an eventlink in a nested component.
Date Tue, 19 Feb 2019 15:40:38 GMT
The idea of passing blocks to layout sounds good to customize content in
different areas.
For event handling I still have to either
1) introduce a super class for all page classes to handle the event and
trigger the refresh
2) or add the event handler on almost all pages I have.

So inheritance seems to be a more pragmatic choice to me.
I have also come across template inheritance feature of Tapestry:
http://tapestry.apache.org/component-templates.html
Creating the layout as the super class of pages and use both java and
template inheritance looks like the most pragmatic choice (no need to pass
around blocks, but I can replace the parts in the parent template)

This means the following changes to the code I posted originally:

*Page: ShowSweepstakes.tml file:*
<t:extend xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p="tapestry:parameter">
<t:replace id="LayoutBody">
    <t:sweepstake.ShowSweepstakes  />
</t:replace>
</t:extend>

*Layout.tml component*
<t:extend xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p="tapestry:parameter">
<t:replace id="FullWidthLayoutBody">
    <div id="layout-container" class="container">
        <div class="row">
            <t:extension-point id="LayoutBody" />
        </div>
    </div>
</t:replace>
</t:extend>

*FullWidthLayout.tml component:*
<html><body>
    <span t:type="zone" t:id="totalPointsZone">${user.totalPoints}</span>
    <t:extension-point id="FullWidthLayoutBody" />
</body> </html>

On the java side the page classes has to also extend the Layout class.


On Sat, 16 Feb 2019 at 13:11, Chris Poulsen <mailinglist@nesluop.dk> wrote:

> Hmm, generally speaking it is the responsibility of the container (page) to
> coordinate its children.
>
> At work we have a couple of places where certain areas of the layout needs
> to be interacted with from the pages. We have chosen to handle the matter
> with block parameters in the layout. Pages that need to have "stuff" in the
> layout use the parameters to add their extra things in the available areas.
>
> In your case you could add a (page) block that contains the zone with the
> stuff for the layout, when the page receives the event, the zone is
> updated.
>
> You could probably also obtain the component resources of the layout
> component and manually trigger an event from the page, but that seems less
> nice to me.
>
> --
> Chris
>
>
>
> On Fri, Feb 15, 2019 at 2:53 PM Balázs Palcsó <palcso.balazs@gmail.com>
> wrote:
>
> > Hi Chris,
> >
> > Yes, that seems to be correct that the layout components with <t:body />
> > (FullWidthLayout and Layout)  are not represented in the component
> > container tree (ComponentPageElement.getContainerElement();) where the
> > event bubbling up happening.
> >
> > Is there any tapestry design pattern to come over this?
> >
> > Most of my pages have the same layout (header, menu, footer, etc) that's
> > why I use these Layout components with the <t:body />, but the
> > FullWidthLayout has a zone that would need to be refreshed too for a
> number
> > of events.
> >
> > Thanks,
> > Balázs
> >
> >
> >
> > On Fri, 15 Feb 2019 at 09:49, Chris Poulsen <mailinglist@nesluop.dk>
> > wrote:
> >
> > > Hi
> > >
> > > I haven't looked much into this, but my guess is that your layout is
> > using
> > > t:body and that confuses things?
> > >
> > > As far as I understand t.body makes a component able to wrap its
> template
> > > around something in its containing component. - That probably means
> that
> > > your stuff wrapped in the layout isn't a child component of the layout,
> > so
> > > your event does not bubble to the layout.
> > >
> > > You can inspect the tapestry component model of the page at runtime
> > (using
> > > a debugger) to see how the actual components are connected.
> > >
> > > If it turns out that your layout does not participate the expected
> place
> > in
> > > your component hierarchy, you could expose various aspects of the
> layout
> > > using parameters, for example allowing access to the zone or pick some
> > > other construct that matches your needs.
> > >
> > > --
> > > Chris
> > >
> > >
> > >
> > > On Thu, Feb 14, 2019 at 10:24 PM Balázs Palcsó <
> palcso.balazs@gmail.com>
> > > wrote:
> > >
> > > > Hello,
> > > >
> > > > Refreshing totalPointsZone from the FullWidthLayout is not working
> when
> > > > participateInSweepstake  async eventlink is clicked
> > > > in sweepstake.ShowSweepstake nested component.
> > > >
> > > > Any suggestions how to get both the participateInSweepstakeZone and
> the
> > > > totalPointsZone refreshed when <t:EventLink
> > > event="participateInSweepstake"
> > > > context="${sweepstake.id}" async="true">Participate is
> > > > clicked</t:EventLink>
> > > >
> > > > *Here is the relevant code snippets from the app:*
> > > >
> > > > *Page: ShowSweepstakes.tml file:*
> > > > <html t:type="layout" xmlns:t="
> > > > http://tapestry.apache.org/schema/tapestry_5_4.xsd">
> > > >     <t:sweepstake.ShowSweepstakes  />
> > > > </html>
> > > >
> > > > *sweepstake.ShowSweepstakes.tml component:*
> > > > <t:container>
> > > >     <loop>
> > > >          <t:sweepstake.ShowSweepstake sweepstake="sweepstake"  />
> > > >    </loop>
> > > > </t:container>
> > > >
> > > > *sweepstake.ShowSweepstake.tml component:*
> > > >    <t:zone t:id="participateInSweepstakeZone"
> > > > id="prop:participateInSweepstakeZoneId">
> > > >             <t:if test="notParticipatedYet">
> > > >                 <t:EventLink event="participateInSweepstake"
> > context="${
> > > > sweepstake.id}" async="true" class="btn btn-danger btn-lg">
> > > >                     Participate for
> > > > ${sweepstake.priceToParticipateInPoints} points
> > > >                 </t:EventLink>
> > > >             <p:else>
> > > >                 <button type="button" class="btn btn-danger btn-lg"
> > > > disabled="disabled">You're already participating</button>
> > > >             </p:else>
> > > >             </t:if>
> > > >         </t:zone>
> > > >
> > > > *ShowSweepstake .java:*
> > > > public class ShowSweepstake {
> > > >     @CommitAfter
> > > >     void onParticipateInSweepstake(final Sweepstake sweepstake) {
> > > >          ....
> > > >
> > > > componentResources.triggerEvent(ComponentEvents.REFRESH_TOTAL_POINTS,
> > > null,
> > > > null);
> > > >         if (request.isXHR()) {
> > > >
> >  ajaxResponseRenderer.addRender(participateInSweepstakeZone);
> > > >         }
> > > >     }
> > > >
> > > > *Layout.tml component*
> > > > <html t:type="FullWidthLayout">
> > > >     <div id="layout-container" class="container">
> > > >         <div class="row">
> > > >             <t:body />
> > > >         </div>
> > > >     </div>
> > > > </html>
> > > >
> > > > *FullWidthLayout.tml component:*
> > > > <html><body>
> > > >     *<span t:type="zone"
> > > t:id="totalPointsZone">${user.totalPoints}</span>*
> > > >     <t:body />
> > > > </body> </html>
> > > >
> > > > *FullWidthLayout .java component*
> > > > public class FullWidthLayout {
> > > >     *@OnEvent(ComponentEvents.REFRESH_TOTAL_POINTS)*
> > > >     private void refreshTotalPoints() {
> > > >         ajaxResponseRenderer.addRender(totalPointsZone);
> > > >     }
> > > > }
> > > >
> > > > Thanks,
> > > > Balazs
> > > >
> > >
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message