admin管理员组文章数量:1134757
I have a Handlebars template where I'm trying to generate a comma-separated list of items from an array.
In my Handlebars template:
{{#each list}}
{{name}} {{status}},
{{/each}}
I want the ,
to not show up on the last item. Is there a way to do this in Handlebars or do I need to fall back to CSS selectors?
UPDATE: Based on Christopher's suggestion, this is what I ended up implementing:
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()
})
}));
and in my view:
{{collection attachments}}
and the item view:
{{content.title}} ({{content.size}}) {{#unless isLastItem}}, {{/unless}}
I have a Handlebars template where I'm trying to generate a comma-separated list of items from an array.
In my Handlebars template:
{{#each list}}
{{name}} {{status}},
{{/each}}
I want the ,
to not show up on the last item. Is there a way to do this in Handlebars or do I need to fall back to CSS selectors?
UPDATE: Based on Christopher's suggestion, this is what I ended up implementing:
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()
})
}));
and in my view:
{{collection attachments}}
and the item view:
{{content.title}} ({{content.size}}) {{#unless isLastItem}}, {{/unless}}
Share
Improve this question
edited May 2, 2012 at 16:58
Chris Thompson
asked May 1, 2012 at 19:20
Chris ThompsonChris Thompson
16.8k9 gold badges48 silver badges62 bronze badges
1
- Another thing that I found out is that if you remove the last item, you need to force a redraw of each item to remove the last separator. By default removing an item seems to only remove the view for that item and the others are not updated (which makes sense). – Chris Thompson Commented May 9, 2012 at 15:54
8 Answers
Reset to default 178I know I'm late to the parts but I found a WAYYYY simpler method
{{#unless @last}},{{/unless}}
Since Ember v1.11 you are able to get the index of an each using block parameters. In your case this would look something like this:
{{#each list as |item index|}}
{{if index ", "}}{{item.name}} {{item.status}}
{{/each}}
The first index
value will be 0
which will evaluate to false
and will not be added, all subsequent values will evaluate to true
which will prepend a separator.
You can use standard CSS to do this:
li:after {
content: ',';
}
li:last-of-type:after {
content: '';
}
I prefer separate rules, but a more concise if slightly less readable version (from @Jay in the comments):
li:not(:last-of-type):after {
content: ',';
}
I have created sep block helper:
Handlebars.registerHelper("sep", function(options){
if(options.data.last) {
return options.inverse();
} else {
return options.fn();
}
});
Usage:
{{#each Data}}
{{Text}}{{#sep}},{{/sep}}
{{/each}}
Supports else statement.
With ember 2.7 you can do this after you install ember-truth-helpers
:
ember install ember-truth-helpers
and then your template will look like this:
{{#each model as |e|}}
{{e}}{{#unless (eq e model.lastObject)}}, {{/unless}}
{{/each}}
I realize this is a year old but I had a similar problem and wound up here. In my case, I was actually dealing with an array. So, here's my solution.
Handlebars.registerHelper('csv', function(items, options) {
return options.fn(items.join(', '));
});
// then your template would be
{{#csv list}}{{this}}{{/csv}}
I was going for a simple and elegant solution that keeps the csv logic in the template.
I got this working with a modified version of freak3dot's answer:
handlebars.registerHelper('csv', function(items, options) {
return items.map(function(item) {
return options.fn(item)
}).join(', ')
})
(This is a node app, so change the map
accordingly to underscore or whatever if you're building in the browser)
Allows for formatting objects between each comma:
{{#csv players}
{{firstName}} {{lastName}}
{{/csv}}
Edit: Here's a more flexible version. Join a list of things on an arbitrary separator.
handlebars.registerHelper('join', function(items, separator, options) {
return items.map(function(item) {
return options.fn(item)
}).join(separator)
})
And template:
{{#join players ' vs '}
{{firstName}} {{lastName}}
{{/join}}
Maybe for this context, you should be creating a view for the collection, not an iteration of views on the member items. In this case, a Handlebar iterator is overkill. In my example below, changes to the firstName or lastName on the Person objects will be bound to the list and update the view.
Template:
{{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('[email protected]', '[email protected]')
});
// 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"});
Below is my original answer, that didn't work for this context.
You should be able to do this with a helper:
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}}
本文标签:
版权声明:本文标题:javascript - How do I add a separator between elements in an {{#each}} loop except after the last element? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736812691a1953957.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论