1

ページの一部を非表示または表示するリンクを作成しようとしています。リンクは再利用可能であり、状態に応じて2つの画像のいずれかを表示する必要があります。

リンクを使用するすべてのページに2つのサブコンポーネントを追加するのはちょっと不格好なので、コンテンツを自動的に追加しながらリンクのように動作するコンポーネントを作成したいと思いました。

これはリンクコンポーネントです:

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の内部について知っている必要があるため、リンク内の本文をスキップできるようにしたいと思います。Wicketの動的マークアップを開始点として使用して、IMarkupResourceStreamProviderを試してみました。グーグルで検索すると、ポスターがPanelを使用している場合にのみそれを機能させることができた別の例を見つけました。また、それも可能でした。ただし、マークアップでリンクのスタイルを設定できないため、リンクを保持し、パネル内にパッケージ化しないようにします。

また、リンクとその本体をカプセル化するための代替案も受け入れています。

4

1 に答える 1

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\">";
    }
  }
}

MyPackageResourceの単純な実装はどこにありPackageResourceますか(なぜそのコンストラクターが保護されているのですか?)。

ToggleVisibilityLink次に、をコンテナに追加するだけです。

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

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

リンクがクリックされると、イベントを介して通知を受け取ります。

于 2012-11-01T12:52:57.677 に答える