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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11754719/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 06:15:07  来源:igfitidea点击:

Wicket container that is hidden when all its child components are hidden

javawicket

提问by Jonik

I have a block level element, a container, that should be hidden when allits child Wicket elements (buttons) are hidden. In other words, if anychild button is visible, the container should be visible.

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

Earlier one of the buttons was always visible if any buttons were, so I used that button to control the visibility of a <wicket:enclosure>, handling all of this purely on HTML side.

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

Now, the specs have changed so that the buttons can be hidden/visible independently, so a simple enclosure won't work anymore (I think).

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

I got it working with something like this:

我得到它的工作是这样的:

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>

Java:

爪哇:

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));

But the Java side is now kind of verbose and ugly, and I was thinking there's probably be a cleaner way to do the same thing. Is there? Can you somehow "automatically" hide a container (with all its additional markup) when none of its child components are visible?

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

(Wicket 1.4, if it matters.)

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

回答by Costi Ciudatu

If you want this to be reusable, you can define it as a IComponentConfigurationBehavior(for wicket version > 1.4.16) that you attach to any containers and then set the container visibility in the onConfigure()method of the behavior:

如果您希望它是可重用的,您可以将其定义为IComponentConfigurationBehavior(对于 wicket 版本 > 1.4.16)附加到任何容器,然后onConfigure()在行为方法中设置容器可见性:

class AutoHidingBehavior extends AbstractBehavior {

    @Override
    public void bind(Component component) {
        if (! (component instanceof MarkupContainer) ) {
            throw new IllegalArgumentException("This behavior can only be used with markup containers");
        }
    }

    @Override
    public void onConfigure(Component component) {
        MarkupContainer container = (MarkupContainer) component;
        boolean hasVisibleChildren = false;
        for (Iterator<? extends Component> iter = container.iterator(); iter.hasNext(); ) {
            if ( iter.next().isVisible() ) {
                hasVisibleChildren = true;
                break;
            }
        }
        container.setVisible(hasVisibleChildren);
    }

}

回答by Nicktar

You could override the container's isVisiblemethod to return true if any of the childs is visible (evaluating child visibility like you do now). This wouldn't reduce the code drastically but it would be 'nicer' in my eyes because the code determining visibility would be where it 'belongs'. You could make this a specialized container-class to further encapsulate the code.

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

Or you could subclass EnclosureContainerand add whatever visibility-logic you need.

或者您可以子类化EnclosureContainer并添加您需要的任何可见性逻辑。

Note: When overriding isVisible...

注意:当覆盖 isVisible 时...

[...]be warned that this has a few pitfalls:

  • it is called multiple times per request, potentially tens of times, so keep the implementation computationally light

  • this value should remain stable across the render/respond boundary. Meaning if isVisible() returns true when rendering a button, but when the button is clicked returns false you will get an error

[...] 请注意,这有一些陷阱:

  • 每个请求都会调用多次,可能是数十次,因此请保持实现的计算量

  • 这个值应该在渲染/响应边界上保持稳定。意思是如果 isVisible() 在渲染按钮时返回 true,但是当按钮被点击时返回 false 你会得到一个错误

from Wicket in Action

来自Wicket 在行动

回答by Mr Jedi

You can also use visitor.

您也可以使用访客。

In my case I have container with links in Panel. Code:

就我而言,我在面板中有带有链接的容器。代码:

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);
            }
         }
      });
   }

}