ユーザーの冷蔵庫の内容を表示するWebアプリケーションについて考えてみます。特に、現在冷蔵庫にある果物のリストを表示する必要があります。果物の種類ごとに、非常に異なる表示が必要です。最も重要なことは、さまざまな種類の果物がたくさんあることです。
Mustacheテンプレートライブラリを使用してこれを実装したいのですが、最善のアプローチが何であるかはよくわかりません。
手始めに、各フルーツのテンプレートは次のとおりです。
{{! apple.mustache }}
A {{appleType}} apple from {{groceryStore}}
{{! orange.mustache }}
An orange from {{countryOfOrigin}}
{{! banana.mustache }}
A {{ripeness}} banana
...many more templates here...
アプローチ1
「ビューモデル」または「ビューヘルパー」オブジェクトに、「isBanana」/「isOrange」などを作成してテンプレートデータを準備させます。テンプレートに渡されるキー。この場合、冷蔵庫のテンプレートは次のようになります。
You have the following food in your fridge:
{{#fruits}}
{{#isApple}}
{{> apple}}
{{/isApple}}
{{#isOrange}}
{{> orange}}
{{/isOrange}}
{{#isBanana}}
{{> banana}}
{{/isBanana}}
...more conditionals....
{{/fruits}}
私はこのアプローチがインターネット上のいくつかの場所を推奨しているのを見てきました。ただし、どのように拡大縮小するかはわかりません。新しいフルーツタイプを追加するたびに、冷蔵庫のテンプレートを変更する必要があります。また、Mustacheの「ロジックレス」哲学に反しているようです。
アプローチ2
ビューモデルが各フルーツタイプの正しいテンプレートを決定し、それをレンダリングし、テンプレートのデータとしてHTMLを返すようにします。冷蔵庫のテンプレートは次のようになります。
You have the following food in your fridge:
{{{fruits}}}
そしてビューモデル:
class InventoryViewModel
{
// ...
function getFruits()
{
foreach ($this->fridge->getFruits() as $fruit) {
if ($fruit instanceof Banana) {
$html .= $this->mustache->render(...);
} elseif ($fruit instanceof Apple) {
$html .= $this->mustache->render(...);
} else {
// ...
}
}
return $html;
}
}
最初のオプションよりも優れているように見えますが、各ビューモデルに口ひげテンプレートレンダリングオブジェクトを挿入する必要があります。可能であれば、この結合は避けたいと思います。
アプローチ3
公式のMustache仕様の一部ではないある種のテンプレート構成機能を使用します。(https://github.com/janl/mustache.js/pull/242、https://github.com/mustache/spec/issues/38など)。
これらのオプションのどれが最適で、その理由は何ですか?私はもっと良いものを見落としていますか?