2012-01-05 12 views
27

私はmustache.jsを使ってJavaScriptをテンプレートにレンダリングしています。次の例では、リストが空であるかどうかをチェックして、<h2>タグを非表示にしたいと考えています。これは可能なのですか、またはmustache.jsも論理的ではありませんか?mustache.jsの空のリストを扱う

これはテンプレートです:

<h2>Persons:</h2> 
<ul> 
    {{#persons}} 
    {{name}} 
    {{/persons}} 
</ul> 

、これはデータです:

{ 
    "persons":[ 
    {"name": "max"}, 
    {"name": "tom"} 
    ] 
} 
+3

"data"は有効なJSONではありません。 –

+2

また、ひげそりから[ハンドルバー](http://handlebarsjs.com/)に切り替えることについて考えてみてください。これははるかに上手くいくことができますか?これは、誰かが口頭で空リストテスト(https://github.com/defunkt/mustache/issues/47)を求めた(そして拒否された)初めてのことではありません。 –

+0

@MДΓΓLLLLあなた自身の答えを投稿し、あなたのおかれたカルマポイントを盗むことで、あなたのコメントを回答しない(あなたが喜んで投票した)あなたを罰しています。 – andrewrk

答えて

26

テンプレートロジックレスを維持するには、テンプレートをレンダリングする前に、このチェックを行うことができます。半日のために奮闘した後

<h2>Persons:</h2> 
{{#hasPersons}} 
<ul> 
    {{#persons}} 
    <li>{{name}}</li> 
    {{/persons}} 
</ul> 
{{/hasPersons}} 
+8

これは正解と同じくらい、この種のアプローチを使用しなければならないのは、Mustache構文の本当の弱点の兆候です。フロントエンド(テンプレート)の開発者がバックエンド(データソース)コードにアクセスできる限り、おそらくOKですが、2つが別々の場合や、フロントエンドの開発者がコーダーよりもHTMLスリンガーの方であれば、うまくいかない。 –

+7

@TimHoltまあ、私は間違いなくあなたのポイントを得る。しかし、利点があります。アプリのこの部分を単体テストしたいと仮定しましょう。ロジックのないテンプレートエンジンでは、(Mustacheにフィードされる前に)データを単体テストするだけで済み、結果のHTMLに対して文字列比較テストを行う必要はありません。さて、私のテンプレートがロジックを持っていれば(たとえ.length> 0をチェックするだけでも)、私はそのロジックを単体テストする必要があると感じるでしょうし、そうすれば文字列比較やセレン/ 。それは私の意見ではトレードオフです。 –

+3

テンプレートの目的は、モデルとコントローラからビューを分離することです。この解決策は基本的に、メタ情報をコントローラに表示することです。 Mustacheがあなたにこれらのことをさせるという事実は、それ自身の目的を破ります。テンプレートはロジックレスであってはいけません(if-statementも論理ですので、とにかくロジックレスではありません)が、テンプレートにはビューロジックとアプリケーションロジックは含まれていません。 –

6

ではなくhandlebarsを使用してください。それはあなたに必要なパワーを少しだけ与えるMustacheのスーパーセットです。口ひげのコミュニティはこの機能を要求しましたが、メンテナーはrefuses to put it inです。

34

// assuming you get the JSON converted into an object 
var data = { 
    persons: [ 
     {name: "max"} 
     , {name: "tom"} 
    ] 
}; 
data.hasPersons = (data.persons.length > 0); 

次に、あなたのテンプレートは次のようになります。この問題で、私はついに簡単な解決策を見つけました!

リストを確認しないで、最初の項目が空でないかどうかを確認してください。

テンプレート:

{{#persons.0}} 
<h2>Persons:</h2> 
<ul> 
    {{#persons}} 
    <li>{{name}}</li> 
    {{/persons}} 
</ul> 
{{/persons.0}} 
{{^persons.0}}No persons{{/persons.0}} 

データ:

{ 
    "persons":[ 
    {"name": "max"}, 
    {"name": "tom"} 
    ] 
} 

出力:

<h2>Persons:</h2> 
<ul> 
    <li>max</li> 
    <li>tom</li> 
</ul> 

データ:

{ 
    "persons": [] 
} 

出力:

"No Persons" 
+0

この回答は受け入れられるべきです!それは一般的な、ひげそりの唯一の解決策は、JavaScriptを想定していない – Evgeny

+0

それは私のために働かなかった。私はMustashe.javaを使用しています。空の条件付きの欠如は、私のためのディール・ブレーカーです。 FreeMarkerに戻る... – dhalsim2

+0

これは動作します。追加するのと同じように、{{#。}}を使用してループされている名前のないリストに対しては、{{^。}}人物{{/}}は使用できません。 – Blizwire

39

persons.lengthを使用できます。真理値(すなわち、0より大きい)であれば、ブロックがレンダリングされる。

あなたが(例えばpystacheまたはScalate中)のjavascriptの外にいる場合、あなたは運の出ている {{#names.length}}{{/names.length}}または {{#names.0}}

で確認することができますJavaScriptで

{{#persons.length}} 
<h2>Persons:</h2> 
<ul> 
    {{#persons}} 
    <li>{{name}}</li> 
    {{/persons}} 
</ul> 
{{/persons.length}} 
+5

サーバーサイド(JavaScript外)をレンダリングしている場合、これは動作しません – iwein

+2

@iwein:結局のところ、質問は「javascript」とタグ付けされていて、ノードでも動作します:) @Qazzian:+1口ひげのラムダを避ける方法! –

+2

@ o.v。私はこの回答にupvoteを与えました、心配しないでください。コメントの追加情報は私にとっては役に立ちました。 – iwein

4

。唯一の解決策は、別のブール値を導入することです。または、配列にオブジェクトを入れ子にすることです。これは、maxbeattyのように配列が空の場合は避けてください。

関連する問題