Fight the Future

Java言語とJVM、そしてJavaエコシステム全般にまつわること

Introducing Apache Wicketの超意訳(10)

http://www.theserverside.com/tt/articles/article.tss?l=IntroducingApacheWicket

The next step is to update the BasePage to use the new SearchPanel:

次のステップとして生成したSearchPanelを使ってBasePageを更新します。

public BasePage() {
    add(new StyleSheetReference("stylesheet",
          BasePage.class, "styles.css"));
    add(new SearchPanel("searchPanel"));
}

The markup also needs to be updated:

マークアップも更新する必要があります。

<html>
<head>
<title>Introduction to Apache Wicket - Example Application</title>
<link wicket:id="stylesheet"/>
</head>

<body>

<h1>
My Contacts
</h1>

<span wicket:id="searchPanel"></span>

<wicket:child/>

</body>
</html>

Instead of StyleSheetReference, we could've used Wicket's HeaderContributor class or the element.
Next, we'll create the ListContacts page, starting with the Java class:

StyleSheetReferenceの代わりにWicketのHeaderContributorクラスや要素を使ってもよいです。
次に、ListContactsページを作りましょう。Javaクラスから始めます。

public class ListContacts extends BasePage {

    public ListContacts(PageParameters params) {
        final String searchString = params.getString("searchString");
        IModel contactsModel = new LoadableDetachableModel() {
            protected Object load() {
                ContactDao dao = WicketApplication.get().getContactDao();
                return dao.find(searchString);
            }
        };

        ListView contacts = new ListView("contacts", contactsModel) {
            protected void populateItem(ListItem item) {
                Link view = new Link("view", item.getModel()) {
                    public void onClick() {
                        Contact c = (Contact) getModelObject();
                        setResponsePage(new ViewContact(c.getId()));
                    }
                };
                view.add(new Label("firstName",
                    new PropertyModel(item.getModel(), "firstName")));
                view.add(new Label("lastName",
                    new PropertyModel(item.getModel(), "lastName")));
                item.add(view);

                item.add(new SmartLinkLabel("email",
                    new PropertyModel(item.getModel(), "email")));
                item.add(new Link("edit", item.getModel()) {
                    public void onClick() {
                        Contact c = (Contact) getModelObject();
                        setResponsePage(new EditContact(c.getId()));
                    }
                });
                item.add(new Link("delete", item.getModel()) {
                    public void onClick() {
                        Contact c = (Contact) getModelObject();
                        WicketApplication.get().getContactDao().delete(c.getId());
                        setResponsePage(ListContacts.class);
                    }
                });
            }
        };
        add(contacts);
    }
}

The heart of ListContacts is a ListView, which is a type of repeater.
The markup contained within the ListView's component ID is repeated for each object passed in through the model.
Here's the markup for our ListView:

ListContactsの核は繰り返しの型であるListViewです。
ListViewのコンポーネントIDの中に含まれるマークアップを、モデルを通じて渡した各オブジェクトに対して繰り返し適用します。
ListViewのマークアップは次のようなものです。

<div wicket:id="contacts" class="contact">
    <table>
        <tr>
            <td>
                <a wicket:id="view" href="#">
                    <span wicket:id="firstName"></span>
                    <span wicket:id="lastName"></span>
                 </a>
            </td>
            <td wicket:id="email"></td>
            <td class="manage-contact-links">
                <a wicket:id="edit" href="#">Edit</a>
                <a wicket:id="delete" href="#">Delete</a>
            </td>
        </tr>
    </table>
</div>

ListView's populateItem(ListItem) method is called for each object, which is how the rows in the contacts table are populated.
The current object is available through ListItem's getModel() and getModelObject() methods, which we've used to populate various labels and links.
(The SmartLinkLabel component is available in the Wicket Extensions project.)
Let's take a closer look at the links added to the ListItem:

ListViewのpopulateItem(ListItem)メソッドを各オブジェクトに対して呼び出します。contactsテーブルにある行をどのように投入するかを定めます。
現在のオブジェクトはListItemのgetModel()とgetModelObject()メソッドを通じて利用できます。さまざまなラベルとリンクを投入するために使います。
(SmartLinkLabelコンポーネントWicket Extensionsプロジェクトで利用できます。)
ListItemに追加したリンクにより迫ってみましょう。

Link view = new Link("view", item.getModel()) {
    public void onClick() {
        Contact c = (Contact) getModelObject();
        setResponsePage(new ViewContact(c.getId()));
    }
};
view.add(new Label("firstName",
    new PropertyModel(item.getModel(), "firstName")));
view.add(new Label("lastName",
    new PropertyModel(item.getModel(), "lastName")));

item.add(new Link("edit", item.getModel()) {
    public void onClick() {
        Contact c = (Contact) getModelObject();
        setResponsePage(new EditContact(c.getId()));
    }
});
item.add(new Link("delete", item.getModel()) {
    public void onClick() {
         Contact c = (Contact) getModelObject();
         WicketApplication.get().getContactDao().delete(c.getId());
         setResponsePage(ListContacts.class);
    }
});

All of the links get the ListItem's model, allowing them to access properties of the contact if necessary.
Each has an onClick() method, called when the user clicks the link on the web page.
In the case of the "view" and "edit" links, the Contact model object is retrieved from the Link in order to get the contact's id to pass off to the respective response pages, ViewContact and EditContact.
The delete link is similar, except the contact is deleted outright rather than edited and the user is sent back to the ListContacts page.

リンクはすべてListItemのモデルを引数に取ります。そのためリンクは必要であればcontactのプロパティにアクセスできます。
それぞれonClick()メソッドを持ち、Webページのリンクをユーザがクリックすると呼び出されます。
「view」と「edit」の場合では、各レスポンスページにcontactのIDを渡せるようにcontactのIDを取得するために、ViewContactとEditContactというContactモデルオブジェクトをLinkから取り出します。
「delete」リンクも同様ですが、contactは編集されるというより完全に削除され、ユーザはListContactsページに戻るという点が異なります。