除了最后一个元素之外,如何在{{#each}}循环中的元素之间添加分隔符?
我有一个Handlebars模板,我试图从数组中生成逗号分隔的项目列表。
在我的Handlebars模板中:
{{#each list}} {{name}} {{status}}, {{/each}}
我想要的,
不要在最后一个项目上显示。 有没有办法在Handlebars中做到这一点,或者我需要回退到CSSselect器?
更新 :根据克里斯托弗的build议,这是我最终实现的:
var attachments = Ember.CollectionView.extend({ content: [], itemViewClass: Ember.View.extend({ templateName: 'attachments', tagName: 'span', isLastItem: function() { return this.getPath('parentView.content.lastObject') == this.get('content'); }.property('parentView.content.lastObject').cacheable() }) }));
在我看来:
{{collection attachments}}
和项目视图:
{{content.title}} ({{content.size}}) {{#unless isLastItem}}, {{/unless}}
你可以使用标准的CSS来做到这一点:
li:after { content: ','; } li:last-of-type:after { content: ''; }
我更喜欢单独的规则,但更简洁,如果可读性稍差一些(来自@Jay评论):
li:not(:last-of-type):after { content: ','; }
我知道我已经迟到了,但是我发现了一个简单的WAYYYY方法
{{#unless @last}},{{/unless}}
自Ember v1.11以来,您可以获取每个使用块参数的索引。 在你的情况下,这看起来像这样:
{{#each list as |item index|}} {{if index ", "}}{{item.name}} {{item.status}} {{/each}}
第一个index
值将是0
,它将被评估为false
并且不会被添加,所有后续的值将评估为true
,这将预先分隔。
我意识到这已经一岁了,但是我也遇到了类似的问题,并且在这里结束了。 就我而言,我实际上正在处理一个数组。 所以,这是我的解决scheme。
Handlebars.registerHelper('csv', function(items, options) { return options.fn(items.join(', ')); }); // then your template would be {{#csv list}}{{this}}{{/csv}}
我正在寻求一种简单而优雅的解决scheme,将csv逻辑保存在模板中。
我得到这个与freak3dot的答案的修改版本工作:
handlebars.registerHelper('csv', function(items, options) { return items.map(function(item) { return options.fn(item) }).join(', ') })
(这是一个节点的应用程序,所以改变map
相应的下划线或任何如果你在浏览器中build设)
允许在每个逗号之间格式化对象:
{{#csv players} {{firstName}} {{lastName}} {{/csv}}
编辑:这是一个更灵活的版本。 join一个任意分隔符的东西列表。
handlebars.registerHelper('join', function(items, separator, options) { return items.map(function(item) { return options.fn(item) }).join(separator) })
和模板:
{{#join players ' vs '} {{firstName}} {{lastName}} {{/join}}
我已经创build了sep块帮手:
Handlebars.registerHelper("sep", function(options){ if(options.data.last) { return options.inverse(); } else { return options.fn(); } });
用法:
{{#each Data}} {{Text}}{{#sep}},{{/sep}} {{/each}}
支持else语句。
使用ember 2.7,你可以在安装ember-truth-helpers
之后做到这一点:
ember install ember-truth-helpers
然后你的模板将如下所示:
{{#each model as |e|}} {{e}}{{#unless (eq e model.lastObject)}}, {{/unless}} {{/each}}
也许对于这个上下文,你应该为集合创build一个视图,而不是成员项目的迭代视图。 在这种情况下,Handlebar迭代器是矫枉过正的。 在我下面的例子中,对Person对象的firstName或lastName的更改将被绑定到列表并更新视图。
模板:
{{App.listController.csv}}
使用Javascript:
App = Ember.Application.create(); var Person = Ember.Object.extend({ firstName: null, lastName: null }); var bob = Person.create({ firstName: "bob", lastName: "smith" }); var ann = Person.create({ firstName: "ann", lastName: "doe" }); App.listController = Ember.Object.create({ list: [bob, ann], csv: Ember.computed(function () { var arr = []; this.get('list').forEach(function (item, index, self) { arr.push(item.firstName + ' ' + item.lastName); }) return arr.join(','); }).property('list.@each.firstName', 'list.@each.lastName') }); // any changes to bob or ann will update the view bob.set('firstName', 'tim'); // adding or removing from the array will update the view App.listController.get('list').pushObject(Person.create(firstName: "Jack", lastName:"Dunn"});
以下是我的原始答案,在这种情况下不起作用。
你应该可以用助手做到这一点:
Handlebars.registerHelper('csv', function(items, options) { var out = ""; for(var i=0, l=items.length; i<l; i++) { out += options.fn(items[i]); if (i < l - 1) { out += ','; } // might want to add a newline char or something } return out; }); // then your template would be {{#csv list}} {{name}} {{status}} {{/each}}