0

ユーザーの冷蔵庫の内容を表示する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など)

これらのオプションのどれが最適で、その理由は何ですか?私はもっ​​と良いものを見落としていますか?

4

1 に答える 1

3

おそらく最も簡単なのは、ViewModelで高次のセクション(ラムダセクション)を使用して、パーシャルを選択することです。

基本テンプレートは次のようになります。

{{# items }}
  {{# getPartial }}{{ type }}{{/ getPartial }}
{{/ items }}

もちろん、あなたの果物が「タイプ」を持っていると仮定します。次に、次の上位セクションを追加しますgetPartial

<?php

class InventoryViewModel
{
    // ...

    function getPartial()
    {
        // you could do string manipulation here,
        // but I prefer the explicitness of a `case`

        return function($tpl, $mustache) {
            switch ($mustache->render($tpl)) {
                case 'Banana':
                    return '{{> banana }}';
                case 'Apple':
                    return '{{> apple }}';
                case 'Orange':
                    return '{{> orange }}';
            }
        };
    }
}

この場合、テンプレートは、ロジックを付随するViewModelに移動することで「ロジックフリー」のままになり、ユニットテストやモックなどを行うことができます。

于 2013-02-11T21:02:45.643 に答える