LoginSignup
3
4

More than 5 years have passed since last update.

Wicket7のComponent queueingを試してみた

Last updated at Posted at 2015-07-09

はじめに

Apache Wicket 7.0.0 のリリースが目前に迫っています。楽しみですね。

ところで、以前のマイルストーンリリースの時に、

という話があったのを思い出したので、Component queueingを試してみました。
結論から言うと、wicket:idが被らなければとても良い感じです。

Component#queue(Component)

Formをもつ、以下の様なHTMLをWicketで制御したいとします。

HomePage.html(Body内を抜粋)
<body>
  <div>
    <div wicket:id="feedback"></div>
    <form wicket:id="form">
      名前:<input type="text" wicket:id="name" /><br />
      番号:<input type="text" wicket:id="index"/><br /> 
      <input type="submit" />
    </form>
    <h1 wicket:id="result"></h1>
  </div>
</body>

このページを Wicket 6 までの作り方で構築する場合、HomePage.javaでは

HomePage.java(の一部。Wicket6の場合)
Form<Void> form = new Form<Void>("form") {
  // -- snip --
}
add(form);
form.add(new TextField<String>("name", nameModel));
form.add(new TextField<String>("index", nameModel));
add(new Label("result", resultModel));

といった様に、<form><input>FormTextField)の階層構造、つまりHTML上のwicket:idの階層構造をもとに、Javaコード上でも同じ階層構造となるように意識して親子のコンポーネントをaddする必要がありました。

Wicket 7 から採用されるComponent queueingでは、wicket:idが重複しない限り

HomePage.java(の一部。Wicket7の場合)
queue(new Form<Void>("form") {
  // -- snip --
});
queue(new TextField<String>("name", nameModel));
queue(new TextField<String>("index", nameModel));
queue(new Label("result", resultModel));

といった様に、wicket:idの階層を意識せずにコンポーネントを準備できるようになります。

よりすっきりとしたコードになって気持ちいいですね。

wicket:idが重複したら?

ページ内でwicket:idが重複してしまった場合は、従来通りwicket:idの階層構造にもとづいてqueueメソッドを使います。

たとえば、上記のHomePage.htmlの"result""name"というwicket:idだったとしたら、

Form<Void> form = new Form<Void>("form") {
  // -- snip --
});
queue(form);
form.queue(new TextField<String>("name", nameModel));
form.queue(new TextField<String>("index", nameModel));
queue(new Label("name", resultModel));

というように、従来と同じ書き方(addがqueueに変わっただけ)になってしまいます。

ここだけを注視すると「addでいいんじゃね?」という声もわき上がってきそうですが...(注1)

一部を除いてJavaコードを書くときにHTML(wicket:id)の階層を意識しなくてもよいという開放感が、現状のqueueの嬉しい所ではないでしょうか。

おわりに

個人的にはWicketのテストケースの様に

queue(new TextField("form:name", nameModel));

みたいに書けるとより気持ちいいなーと思いますが、残念ながらこれはできません(注2)。そのため、全てのコンポーネントをフラットにqueueで追加するためには、たとえば、アンダースコアつなぎのユニークなwicket:idを考えるとかいう前提の元になっちゃいそうです(それはそれで悪手な気が...)。

なので、Wicket 7 を採用する場合は、

  • add原理主義
  • queueを受け入れ、原則はqueueで、どうしても重複する場合は階層構造前提で

というどちらかのやり方で統一するのが妥当かなと思います。

最後に、上のHomePage.htmlに対してWicket7で作ってみたHomePage.javaの内容を記載しておきます(動作確認優先で書いていますので、Modelの使い方などはご容赦ください)。

HomePage.java
public class HomePage extends WebPage {

  public HomePage() {
    IModel<String> nameModel = Model.of("");
    IModel<Integer> indexModel = Model.of(1);
    IModel<String> resultModel = Model.of("");

    queue(new FeedbackPanel("feedback"));

    queue(new StatelessForm<Void>("form") {
      @Override
      protected void onSubmit() {
        super.onSubmit();
        List<String> omikujis = Stream.of("大吉", "中吉", "小吉", "吉", "凶")
                      .collect(Collectors.toList());
        Collections.shuffle(omikujis);
        String result = nameModel.getObject() 
                      + "さんの運勢は..."
                      + omikujis.get(indexModel.getObject() - 1);
        resultModel.setObject(result);
      }
    });

    queue(new RequiredTextField<String>("name", nameModel) {
      @Override
      protected void onInitialize() {
        super.onInitialize();
        add(StringValidator.lengthBetween(1, 10));
        add(new HTML5Attributes());
        setLabel(Model.of("名前"));
      }
    });

    queue(new RequiredTextField<Integer>("index", indexModel, Integer.class) {
      @Override
      protected void onInitialize() {
        super.onInitialize();
        add(RangeValidator.range(1, 5));
        add(new HTML5Attributes());
        setLabel(Model.of("番号"));
      }
    });

    queue(new Label("result", resultModel) {
      @Override
      protected void onConfigure() {
        super.onConfigure();
        setVisible(!Objects.equals(getDefaultModelObjectAsString(), ""));
      }
    });
  }
}

ぜひ皆さんも Wicket 7 で楽しいコンポーネントキューイング生活を送ってみませんか。


  • 注1)初めてユーザーガイドを読んだ時は、私も「addでいいんじゃね...」って思いました。
  • 注2)wicket:idでは:が禁則文字として扱われていたりします。form:nameの様に階層構造を指定できるのは、Wicketが自動的に生成するときか、テストケースの時だけのようです。
3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4