演習: テンプレート
この章では、一覧の動的表示と共通部分のフラグメント化を扱います。B- は本文の書店アプリ bookstore、T- はタスク管理アプリ tasks の問題です。
B-2. ヘッダーのフラグメント化
Section titled “B-2. ヘッダーのフラグメント化”B-1 では、同じヘッダーを home.html・about.html・books/new.html の 3 ファイルにコピーしました。本文 共通レイアウトの部品化 で学んだフラグメントで、このヘッダーを 1 か所にまとめます。
やること
fragments/layout.htmlに、B-1 のヘッダーをth:fragment="header"として定義するhome.html・about.html・books/new.htmlのヘッダーをth:replace="~{fragments/layout :: header}"に置き換える
見た目は B-1 と変わりません。ヘッダーの定義が 1 か所になり、変更も 1 か所で済みます。
ヒント
ヘッダーは全ページ同じ内容なので、本文の <head> と違って引数は要りません。定義は th:fragment="header"、挿入は th:replace="~{fragments/layout :: header}" です。
T-3. Task クラスと動的な一覧
Section titled “T-3. Task クラスと動的な一覧”T-2 ではタスク一覧をテンプレートに直接書きました。ここで Task クラスと Model を使い、一覧を動的に表示します。
Task クラス
- フィールド:
title(String)、completed(boolean) - コンストラクターで 2 つを受け取る
- getter:
getTitle()、isCompleted()
コントローラー
/tasksでList<Task>をModelに渡す。この章では固定のリストで、DB からの取得は後の章
テンプレート tasks.html
th:eachでタスクを 1 件ずつ表示し、th:textでタイトルを出す- 完了したタスクには
completedクラスを付ける - タスクが 0 件のときは「タスクがありません」と表示する
デザイン
- 一覧の見た目は T-2 の CSS をそのまま使う
- 0 件のメッセージは文字色
#999
完成イメージ:
ヒント
th:each="task : ${tasks}" で 1 件ずつ取り出し、${task.title} でタイトルを表示します。完了したタスクのクラスは、本文 th:class による属性の設定 と同じく th:class="${task.completed} ? 'completed' : ''" で付けます。
0 件かどうかは、本文 th:if による表示の切り替え と同じく th:if="${#lists.isEmpty(tasks)}" で判定します。