web-dev-qa-db-ja.com

Thymeleaf、フラグメント、およびデフォルトのパラメーター

Fragment.htmlファイルを作成しました。次のフラグメントが含まれています。

<div th:fragment="my_fragment(content)">
    <p th:text="${content}"></p>
</div>

上記のフラグメントをビューファイルに配置します。

<div th:replace="fragments :: my_fragment('test')"></div>

ここで、my_fragmentに2つのパラメーターを渡しますが、下位互換性を確保する必要があります。

私は次のように問題を解決しようとしました:

<div th:fragment="my_fragment(content, defaultParameter='default value')">
    <p th:text="${content}"></p>
</div>

残念ながら、上記のソリューションはエラーを生成しました:

org.springframework.web.util.NestedServletException:リクエストの処理に失敗しました。ネストされた例外はorg.thymeleaf.exceptions.TemplateProcessingException:フラグメントを解決できません。シグニチャー「my_fragment(content、defaultParameter = 'default value')」は2つのパラメーターを宣言しますが、フラグメント選択は1つのパラメーターを指定します。フラグメントの選択が正しく一致しません。

何か案が?

30
user3364391

Thymeleafは、次のような明示的なパラメーターなしでフラグメントの署名を許可します。

<div th:fragment="my_fragment">
    <p th:text="${content}"></p>
    <p th:text="${defaultParameter}"></p>
</div>

このフラグメントを呼び出してcontentdefaultParameterを渡すには、次のようにフラグメントを呼び出します。

<!-- both parameters not specified -->
<div th:replace="fragments :: my_fragment"></div>
<!-- only content parameter specified -->
<div th:replace="fragments :: my_fragment(content='a')"></div>
<!-- both parameters specified -->
<div th:replace="fragments :: my_fragment(content='a', defaultParameter='b')"></div>

ただし、以下は機能しません。

<div th:replace="fragments :: my_fragment('a', 'b')"></div>

そして、メッセージは自己説明的です:

 Signature "my_fragment" declares no parameters, but fragment selection did specify parameters in a synthetic manner (without names), which is not correct due to the fact parameters cannot be assigned names unless signature specifies these names. 

したがって、下位互換性を維持する場合は、フラグメントの呼び出し中に名前付きパラメーターを使用し、フラグメントの署名にパラメーターを指定しないでください。

44
Rafal Borowiec

フラグメントのオプションパラメータを許可する最良の方法は、「th:with」で宣言し、意味のあるデフォルト値で記述することです。

そのため、フラグメントの宣言タグで必須値とオプション値を明示的に定義します。

以下に、1つの必須パラメーターと2つのオプションパラメーターを使用した簡単な例を示します。

<div th:fragment="printGreetings (name)" th:with="title=${title} ?: 'Mr.', greeting=${greeting} ?: 'Hello'">
    <span th:text="${greeting}">Hello</span>
    <span th:text="${title}">Mr.</span>
    <span th:text="${name}">John Doe</span>
</div>

その後、次のように呼び出すことができます。

<div th:replace="fragments :: printGreetings (name='daniel')">
   Hello Mr. Daniel
</div>
<div th:replace="fragments :: printGreetings (name='Lea', title='Ms.')>
   Hello Ms. Lea
</div>
<div th:replace="fragments :: printGreetings (name='Lea', title='Ms.', greeting='Hi')>
   Hi Ms. Lea
</div>

(タグ内のすべての値が動的な値に置き換えられることに注意してください。これは単に読みやすくするためです。)

11
snap

(あなたの場合のように)デフォルト値を提供したい場合、elvis演算子を使用してデフォルト値を指定できます。次に例を示します。

<div th:fragment="my_fragment">
    <p th:text="${content}"></p>
    <p th:text="${defaultParameter ?: 'the backwards compat value'}"></p>
</div>

参照: elvis-operator

5

最後に、私はこのようなタスクを解決しました:

<div th:fragment="my_fragment2(content, param2)">
    <th:block th:replace="my_fragment(${content})"/>
</div>

<div th:fragment="my_fragment(content)" th:with="param2=${param2} ?: 'default value'">
    <p th:text="${content}"></p>
    <p th:text="${param2}"></p>
</div>

<div th:replace="fragments :: my_fragment2('test', 'my_value')"></div>

しかし、それはオーバーヘッドです:(

また、発行する質問をします フラグメントパラメータにデフォルト値を持たせる

1
GKislin