macha_7
@macha_7

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

【Thymeleaf】引数なし fragment の呼び出し元で、パラムを渡してもエラーにならないのはなぜ?

概要

Tyhmeleaf の fragment の引数について、「デフォルト値」を設定することはできないため、th:with を利用して疑似デフォルト値を実装しました。

実装例

呼び出し元:

<div th:replace="this::item(name=${name})"></div>

Fragment側:

<th:block th:fragment="item()" th:with="name=${name} ?: 'default_name'">
  <span>[[${name}]]</span>
</th:block>

気になる点

呼び出し先の fragment には引数を定義してませんが、呼び出し元から name を渡しています。
一見、パラム不一致のエラーなりそうですが、実際には動作しています。

質問

  1. Fragment側で引数を受け取る定義がないのに、呼び出し元でパラメータを渡してもエラーにならないのはなぜ?
  2. この書き方はベストプラクティスと言えるのか?

補足

ChatGPT で調べたところ、
動作する可能性はあるが、不安定な実装である」との回答
th:with で変数が未定義の状態で参照されるとエラーになる可能性がある、といった指摘


もし、同じような実装をされた方や、この点について詳しい方がいれば、ご意見をいただけると嬉しいです。

0

1Answer

ヒントになりそうな内容を発見
https://stackoverflow.com/a/22121676

Thymeleaf allows a signature of a fragment without explicit parameters like this:
(Thymeleaf では、次のように明示的なパラメータなしでフラグメントの署名を許可します。)

0Like

Comments

  1. @macha_7

    Questioner

    公式?ガイドにちゃんと記載ありました。
    https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf_ja.html

    フラグメント引数なしでのフラグメントローカル変数

    <div th:fragment="frag">
        ...
    </div>
    
    <div th:replace="::frag (onevar=${value1},twovar=${value2})">
    

    実際のところ、これはth:replaceとth:withを組み合わせて使ったのと同じことです:

    <div th:replace="::frag" th:with="onevar=${value1},twovar=${value2}">
    

    結論:仕様だということ(もっと正確な理解ができそうではある)

  2. @macha_7

    Questioner

    追加調査

    chatGpt に公式ページを読ませて再回答させた
    結果、#vars で変数の存在確認をした方がよいとのこと
    (変数が存在しない場合、エラーになるとか)

    <th:block th:fragment="item()" th:with="name=${#vars.name ?: 'default_name'}">
      <span>[[${name}]]</span>
    </th:block>
    

    これにより、name が未定義の場合でもエラーを回避し、デフォルト値を適用できるとのこと

Your answer might help someone💌