Hi Howard,

Thanks for the quick reply, I really need help with this.

I have three page classes, Index, Page1 and Page2

Template for Index:
<div t:type="MyTheme"
        t:mainMenuId="1" //I'm passing a param for the menu, but I don't want
breadcrumbs on this page
// Other page specific stuff
</div>

Template for Page1:
<div t:type="MyTheme" // I want neither menu nor breadcrumbs on this
// Other page specific stuff
</div>

Template for Page2:
<div t:type="MyTheme" 
        t:breadcrumbId="12"// I want just breadcrumbs on this page
// Other page specific stuff
</div>

I have three components, a layout component, a menu component and a page
component.
This is the source for the layout component

public class MyTheme {

        @Property
        @Parameter(required = false)
        private Integer breadcrumbMenuId;
        
        @Property
        @Parameter(required = false )
        private Integer mainMenuId;

        public boolean isMainMenu(){
                if(mainMenuId != null && mainMenuId != 0)
                        return true;
                return false;
        }
        
        public boolean isBreadcrumb(){
                if(breadcrumbMenuId != null && breadcrumbMenuId != 0)
                        return true;
                return false;
        }

//other code
}

The is the simplified layout component template
<t:if test="mainMenu">
        <t:mainMenu mainMenuId="inherit:mainMenuId" />
</t:if>

<t:if test="breadcrumb">
                <t:breadcrumb breadcrumbMenuId="breadcrumbMenuId" />
</t:if>

This is the code for the breadcrumb component
public class Breadcrumb {
        
        @Inject
        private MenuService menuService;

        @Parameter(required=true)
        private Integer breadcrumbMenuId;
        
        @Property
        private List<MenuItem> menuItems;
        
        @SuppressWarnings("unused")
        @Property
        private MenuItem currentMenuItem;
        
        @SuppressWarnings("unused")
        @Property
        private MenuItem currentPage;
        
        @BeginRender
        void setupBreadcrumb(){
                menuItems = menuService.getMenuItemTree(breadcrumbMenuId);
                currentPage = menuItems.remove(menuItems.size()-1);
        }
}

And the corresponding template
<div class="module"
        xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd";>
<t:loop
        source="menuItems" value="currentMenuItem">
        <a href="${context}${currentMenuItem.link}">${currentMenuItem.text}</a>
        <img src="/images/arrow.png" alt="" />
</t:loop> ${currentPage.text}
</div>

And finally the menu component class

public class MainMenu extends Menu{
        
        @Parameter(required = true )
        private Integer mainMenuId;
        
        @BeginRender
        void setupComponent(){ //The superclass calls a method in the service
to build a composite
                super.setupComponent(mainMenuId);
        }
}

and its template
<div id="menu-mss" class="moomenu"
        xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd";>
<ul class="menutop">
        <t:outputraw value="menu.print()"/> //the menu property comes from the
superclass
</ul>
</div>


Now everything here works fine and I don't get any errors.
This is the general flow of the application.
1. When someone logs in they come to the index page. This page only has
a menu and no breadcrumbs
2. The second page has neither a menu nor a breadcrumb. It simply has a
pagelink to Page2
3. The third page only has the breadcrumb. This is where the problem is.
The breadcrumb component runs two queries to build the breadcrumb for
this page. 
But when I look at the console when this page loads, I see these two
queries, plus four repetitions of the query
for building the menu. The menuId in these queries is the menuId i set
on the Index page(1).
I have no idea how it is still hanging around. If I print it in the
getter/setter or the component, or
in the setupComponent() method and refresh page2, I see that it is
called four times and prints out menuId as 1,
even though I'm not passing it in the page class. However, if I restart
the server and go straight to page2,
then the getter method for menuId is never called and I dont see the
query for the menu in the console.

I tried moving the breadcrumb component to the page class and it does
the same thing. Its almost as if the menuId
parameter passed from the Index page into the component has been
persisted. If i remove the breadcrumb tag in 
the page class, the menu queries don't show up either. If i remove the
<t:mainMenu /> tag from the component, 
again the additional queries disappear.

I tried something like this in the component after making mainMenuId a
prop binding
@AfterRender
void cleanUp(){
    mainMenuId = null;
}
Still the same thing.

I tried setting cache=false on mainMenuId on the component with no luck

My setup uses Tapestry 5.1.0.5, spring 2.5.6 and the latest version of
Hibernate (3.2.x).
Again, I don't get any errors. Its just that it bothers me because I
don't understand why it does that :). Besides, building
the menu is expensive (very recursive), so I don't want to do it if the
page doesn't need it.
This is probably either expected behaviour or I'm just blindly
overlooking something, but in either case, any pointers on
how I can get around this is appreciated.

Thanks in advance,
Jeshurun

Reply via email to