配列からコンマ区切りの項目リストを生成しようとするHandlebarsテンプレートがあります。
私のHandlebarsテンプレートで:
{{#each list}}
{{name}} {{status}},
{{/each}}
,
最後のアイテムに表示されないようにします。 Handlebarsでこれを行う方法はありますか、CSSセレクターにフォールバックする必要がありますか?
[〜#〜] update [〜#〜]:クリストファーの提案に基づいて、これは私が実装したものです:
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
に評価され、区切り文字が追加されます。
私はこれが1年前であることを認識していますが、私は同様の問題を抱えていたのでここにしまいました。私の場合、実際には配列を扱っていました。だから、ここに私の解決策があります。
Handlebars.registerHelper('csv', function(items, options) {
return options.fn(items.join(', '));
});
// then your template would be
{{#csv list}}{{this}}{{/csv}}
テンプレートにcsvロジックを保持するシンプルでエレガントなソリューションを探していました。
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}}
私はこれをfreak3dotの答えの修正版で動作させました:
handlebars.registerHelper('csv', function(items, options) {
return items.map(function(item) {
return options.fn(item)
}).join(', ')
})
(これはノードアプリなので、ブラウザでビルドしている場合は、アンダースコアなどに応じてmap
を変更します)
各コンマの間でオブジェクトをフォーマットできます。
{{#csv players}
{{firstName}} {{lastName}}
{{/csv}}
編集:より柔軟なバージョンを次に示します。任意のセパレータで物事のリストを結合します。
handlebars.registerHelper('join', function(items, separator, options) {
return items.map(function(item) {
return options.fn(item)
}).join(separator)
})
そしてテンプレート:
{{#join players ' vs '}
{{firstName}} {{lastName}}
{{/join}}
たぶん、このコンテキストでは、メンバー項目のビューの反復ではなく、コレクションのビューを作成する必要があります。この場合、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('[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"});
以下は、このコンテキストでは機能しなかった私の最初の答えです。
あなたはヘルパーでこれを行うことができるはずです:
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}}