简体   繁体   English

如何创建一个提供自己的标记的链接?

[英]How to create a Link that supplies its own Markup?

I'm trying to create a link that will hide or show a part of my page. 我正在尝试创建一个链接,该链接将隐藏或显示页面的一部分。 The link should be reusable and display one of two images, depending on state. 该链接应可重用,并根据状态显示两个图像之一。

Adding the two subcomponents on every page where I use the link is kind of clunky so I wanted to create a component that behaves like a link while automatically adding its content. 在使用链接的每个页面上添加两个子组件有点麻烦,因此我想创建一个行为类似于链接的组件,同时自动添加其内容。

This is the Link component: 这是链接组件:

public class ToggleVisibilityLink extends AjaxFallbackLink<Boolean>
{
  public ToggleVisibilityLink(final String id, final IModel<Boolean> model)
  {
    super(id, model);

    setOutputMarkupId(true);

    add(new Image("collapseImage")
    {
      @Override
      public boolean isVisible()
      {
        return !getModelObject();
      }
    });
    add(new Image("expandImage")
    {
      @Override
      public boolean isVisible()
      {
        return getModelObject();
      }
    });
  }

  @Override
  public void onClick(final AjaxRequestTarget target)
  {
    setModelObject(!getModelObject());
    if (target != null)
    {
      target.add(this);
      send(this.getParent(), Broadcast.EXACT, target);
    }
  }
}

And this is how I currently use it in HTML (this is added to the page or panel where I use the link): 这就是我目前在HTML中使用它的方式(将其添加到使用链接的页面或面板中):

<a href="#" wicket:id="collapseExpandLink" class="collapseExpandLink">
  <wicket:link>
    <img src="collapse.png" wicket:id="collapseImage" class="collapseExpandImage collapse">
  </wicket:link>
  <wicket:link>
    <img src="expand.png" wicket:id="expandImage" class="collapseExpandImage expand">
  </wicket:link>
</a>

And the corresponding Java call: 并进行相应的Java调用:

add(new ToggleVisibilityLink("collapseExpandLink", new PropertyModel(this, "hidden")));

But I want to be able to skip the body inside the link as one would have to know about the internals of ToggleVisibilityLink. 但是我希望能够跳过链接内的主体,因为您必须了解ToggleVisibilityLink的内部结构。 I experimented with IMarkupResourceStreamProvider, using Dynamic markup in Wicket as a starting point. 我使用Wicket中的动态标记作为起点,对IMarkupResourceStreamProvider进行了实验。 By googling I found another example where the poster was only able to get that to work when using a Panel , and I was able to do that as well. 通过谷歌搜索,我发现了另一个示例,其中海报仅在使用Panel时才能使之起作用,而我也能够做到这一点。 But I'd really like to keep the link and not package it inside a Panel, as I would not be able to style the link in the markup. 但是我真的很想保留链接,而不是将其打包在Panel中,因为我无法在标记中设置链接的样式。

I'm also open to alternatives to encapsulate the link and its body. 我也乐于接受其他方法来封装链接及其主体。

I was able to get this to work using setBody(), even though I was trying to sabotage myself quite badly (I had duplicate libraries, my own incompatible jQuery library import and a custom resource versioning strategy). 即使我试图严重破坏自己(我有重复的库,我自己不兼容的jQuery库导入和自定义资源版本控制策略),我仍然可以使用setBody()使它起作用。

Here is the current ToggleVisibilityLink: 这是当前的ToggleVisibilityLink:

public class ToggleVisibilityLink extends AjaxFallbackLink<Boolean>
{
  static {
    Application.get().getSharedResources().add("ToggleVisibilityLinkCollapse",
                                               new MyPackageResource(ToggleVisibilityLink.class, "collapse.png"));
    Application.get().getSharedResources().add("ToggleVisibilityLinkExpand",
                                               new MyPackageResource(ToggleVisibilityLink.class, "expand.png"));
  }

  public ToggleVisibilityLink(final String id, final IModel<Boolean> model)
  {
    super(id, model);

    setOutputMarkupId(true);
    setEscapeModelStrings(false);

    setBody(new BodyModel(model));
  }

  @Override
  public void onClick(final AjaxRequestTarget target)
  {
    setModelObject(!getModelObject());
    if (target != null)
    {
      target.add(this);
      send(this.getParent(), Broadcast.EXACT, target);
    }
  }

  private static final class BodyModel extends AbstractReadOnlyModel<String>
  {
    private final IModel<Boolean> model;

    private BodyModel(final IModel<Boolean> model)
    {
      this.model = model;
    }

    @Override
    public String getObject()
    {
      return this.model.getObject() ?
              "<img src=\""
            + RequestCycle.get().urlFor(new SharedResourceReference("ToggleVisibilityLinkExpand"), null)
            + "\" class=\"collapseExpandImage expand\">"
              :
              "<img src=\""
            + RequestCycle.get().urlFor(new SharedResourceReference("ToggleVisibilityLinkCollapse"), null)
            + "\" class=\"collapseExpandImage collapse\">";
    }
  }
}

Where MyPackageResource is a simple Implementation of PackageResource (why is that constructor protected?). 其中MyPackageResourcePackageResource的简单实现(为什么构造函数受到保护?)。

Then one can simply add the ToggleVisibilityLink to a container: 然后,您可以简单地将ToggleVisibilityLink添加到容器中:

super.add(new ToggleVisibilityLink("collapseExpandLink", new PropertyModel(this, "hidden")));

and

<a wicket:id="collapseExpandLink" class="collapseExpandLink"></a>

and get notified via Event when the link is clicked. 并在单击链接时通过事件得到通知。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM