隐藏其所有子组件时隐藏的Wicket容器

时间:2012-08-01 07:43:55

标签: java wicket

我有一个块级元素,一个容器,当 all 隐藏其子Wicket元素(按钮)时,应该隐藏它。换句话说,如果任何子按钮可见,则容器应该是可见的。

如果有任何按钮,其中一个按钮始终可见,因此我使用该按钮来控制<wicket:enclosure>的可见性,完全在HTML端处理所有这些。

现在,规格已经改变,因此按钮可以独立隐藏/可见,因此简单的外壳将不再起作用(我认为)。

我得到了类似的东西:

HTML:

<wicket:container wicket:id="downloadButtons">
     <wicket:message key="download.foo.bar"/>:
     <input type="button" wicket:id="excelDownloadButton" wicket:message="value:download.excel"/>
     <input type="button" wicket:id="textDownloadButton" wicket:message="value:download.text"/>
     <!-- etc ... -->
</wicket:container>

爪哇:

WebMarkupContainer container = new WebMarkupContainer("downloadButtons");

// ... add buttons to container ...

boolean showContainer = false;
Iterator<? extends Component> it = container.iterator();
while (it.hasNext()) {
    if (it.next().isVisible()) {
        showContainer = true;
        break;
    }
}
addOrReplace(container.setVisible(showContainer));

但Java方面现在有点冗长和丑陋,我在想可能有一种更清洁的方法来做同样的事情。在那儿?当它的子组件都不可见时,你能以某种方式“自动”隐藏容器(及其所有附加标记)吗?

(Wicket 1.4,如果重要的话。)

3 个答案:

答案 0 :(得分:10)

如果您希望这可以重复使用,可以将其定义为IComponentConfigurationBehavior(适用于wicket版本&gt; 1.4.16),您可以将其附加到任何容器,然后在{{1}中设置容器可见性行为方法:

onConfigure()

答案 1 :(得分:4)

如果任何子项可见,您可以覆盖容器的isVisible方法返回true(像现在一样评估子可见性)。这不会大幅减少代码,但在我看来它会“更好”,因为确定可见性的代码将是它“属于”的位置。您可以将其设置为一个专门的容器类来进一步封装代码。

或者你可以继承EnclosureContainer并添加你需要的任何可见性逻辑。

注意:覆盖isVisible时......

  

[...]警告说这有一些陷阱:

     
      
  • 每次请求多次调用,可能需要数十次,因此请保持计算结构的轻量化

  •   
  • 此值应在渲染/响应边界内保持稳定。这意味着如果isVisible()在渲染按钮时返回true,   但是当单击该按钮返回false时,您将收到错误

  •   

来自Wicket in Action

答案 2 :(得分:0)

您也可以使用访客。

在我的情况下,我在Panel中有链接的容器。代码:

public abstract class MyPanel extends Panel
{
   private final WebMarkupContainer webMarkupContainer;

   public MyPanel(String id)
   {
      super(id);

      webMarkupContainer = new WebMarkupContainer("customContainer")
      {
         @Override
         protected void onBeforeRender()
         {
            super.onBeforeRender();
            boolean visible = Boolean.TRUE.equals(checkVisibleLinks());
            setVisible(visible);
         }
      };

      AjaxLink myLink = new AjaxLink("myLink")
      {
         @Override
         public void onClick(AjaxRequestTarget target)
         {
            //some action
         }

      };

      webMarkupContainer.add(myLink);
   }

   private Boolean checkVisibleLinks()
   {
      return webMarkupContainer.visitChildren(AbstractLink.class, new IVisitor<AbstractLink, Boolean>()
      {
         @Override
         public void component(AbstractLink link, IVisit<Boolean> visit)
         {
            if (link.isVisible())
            {
               visit.dontGoDeeper();
               visit.stop(true);
            }
         }
      });
   }

}