2012-01-05 70 views
27

我正在使用mustache.js在JavaScript中呈现模板。我想检查一下列表是否为空,或者不在下面的例子中隐藏<h2>标签。这是可能的还是mustache.js太逻辑了?处理mustache.js中的空列表

这是模板:

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

,这是数据:

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

“数据”不是有效的JSON。 – 2012-01-05 16:16:56

+2

另外,你可能想考虑从胡子切换到[handlebars](http://handlebarsjs.com/),它可以更优雅地(我敢说呢?)_handle_这样的情况。这不是第一次有人要求(并且被拒绝)和留在小胡子的空列表测试:https://github.com/defunkt/mustache/issues/47。 – 2012-01-05 16:33:16

+0

@MДΓΓБДLL我在惩罚你,因为没有把你的评论作为一个答案(我会很高兴地投了赞成票),把它作为一个答案我自己,并窃取你的美味的业力点。 – andrewrk 2012-01-22 09:01:15

回答

26

为了使您的模板逻辑少,你可以渲染模板之前做这个检查:

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

那么你的模板将是这样的:

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

尽管这是一个正确的答案,但我认为不得不使用这种方法是胡须语法真正弱点的一个标志。只要前端(模板)开发人员可以访问后端(数据源)代码,也许可以,但如果两者是分开的,或者前端开发人员比编码人员更多地使用HTML slinger,则它会变得非常漂亮不可行的。 – 2012-03-26 17:14:18

+7

@TimHolt,我明白你的观点。虽然有优势。假设您想要对应用程序的这部分进行单元测试。使用无逻辑模板引擎,我只满足于对数据进行单元测试(在提供给Mustache之前),而不必对生成的html进行字符串比较测试。现在,如果我的模板具有逻辑(即使像检查.length> 0那么简单),我也会觉得需要对该逻辑进行单元测试,因此将被迫进行字符串比较或者像selenium/doh机器人。所以,我认为这是一种折衷。 – 2012-04-11 06:17:49

+3

模板的目的是将视图从模型和控制器中分离出来。这个解决方案基本上是将View元信息移动到Controller中。小胡子让你做这些事情的事实打败了它自己的目的。模板不应该是无逻辑的(if语句也是逻辑,所以它不是无逻辑的),但模板应该包含视图逻辑和没有应用逻辑。 – 2015-01-24 17:23:12

34

挣扎了半天后,有了这个问题,我终于找到了一个简单的解决方案!

不检查列表,但检查它的第一个项目是否不是空的!

模板:

{{#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 2014-06-03 00:49:34

+0

它不适合我。我正在使用Mustashe.java。这对缺乏条件的缺乏对我来说是一种破坏行为。返回FreeMarker ... – dhalsim2 2015-05-29 00:46:51

+0

这可行。就像添加一个未命名的列表一样,它使用{{#。}}循环,然后可以使用{{^。}} No Persons {{/。}}。 – Blizwire 2015-09-22 02:07:23

39

您可以使用persons.length。如果它是一个真值(即大于0),那么该块将被渲染。

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

这是行不通的,如果你渲染服务器端(外部javascript) – iwein 2013-07-24 14:58:58

+2

@iwein:问题*被*标记为'''毕竟,它也在节点中工作:) @Qazzian:+1,一个清洁避免胡子lambdas的方法! – 2013-09-25 23:23:40

+2

@ o.v。我给了这个答案一个赞成,不要担心。然而,评论中的其他信息对我很有帮助。 – iwein 2013-09-26 08:18:47

4

在javascript中你可以用{{#names.length}}{{/names.length}}{{#names.0}}

检查如果你的JavaScript之外(例如,在pystache或Scalate的),你的运气了。唯一的解决方案是引入一个单独的布尔值,或者将数组嵌套到一个对象中,如果你有一个空数组,就像maxbeatty建议的那样,这个对象就完全避免了。