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

时间:2012-10-31 22:57:48

标签: java wicket

我正在尝试创建一个隐藏或显示部分页面的链接。该链接应该是可重复使用的,并根据状态显示两个图像中的一个。

在我使用链接的每个页面上添加两个子组件有点笨重,所以我想创建一个行为类似链接的组件,同时自动添加其内容。

这是链接组件:

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

这就是我目前在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>

相应的Java调用:

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

但我希望能够跳过链接中的正文,因为必须知道ToggleVisibilityLink的内部。 我使用Dynamic markup in Wicket作为起点,试验了IMarkupResourceStreamProvider。通过谷歌搜索我找到了另一个例子,海报只能在using a Panel时才能使用,我也能够做到这一点。但是我真的想保留链接而不是将它打包到Panel中,因为我无法在标记中设置链接的样式。

我也愿意接受封装链接及其正文的替代方案。

1 个答案:

答案 0 :(得分:1)

我能够使用setBody()来实现这一点,即使我试图破坏自己非常糟糕(我有重复的库,我自己的不兼容的jQuery库导入和自定义资源版本控制策略)。

这是当前的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\">";
    }
  }
}

MyPackageResourcePackageResource的简单实现(为什么构造函数受到保护?)。

然后可以简单地将ToggleVisibilityLink添加到容器中:

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

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

并在点击链接时通过Event获得通知。