web-dev-qa-db-ja.com

最後の要素の後を除いて、{{#each}}ループの要素間にセパレータを追加するにはどうすればよいですか?

配列からコンマ区切りの項目リストを生成しようとする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}}
55
Chris Thompson

これを行うには、標準のCSSを使用できます。

li:after {
    content: ',';
}

li:last-of-type:after {
    content: '';
}

私は個別のルールを好みますが、少し読みにくいバージョンの場合はより簡潔です(コメントの@Jayから):

li:not(:last-of-type):after {
    content: ',';
}
51

私は部品に遅れていることは知っていますが、WAYYYYのより簡単な方法を見つけました

{{#unless @last}},{{/unless}}
121
MylesBorins

Ember v1.11なので、ブロックパラメータを使用してそれぞれのインデックスを取得できます。この場合、これは次のようになります。

{{#each list as |item index|}}
    {{if index ", "}}{{item.name}} {{item.status}}
{{/each}}

最初のindex値は0これはfalseに評価され、追加されません。後続のすべての値はtrueに評価され、区切り文字が追加されます。

56
Nahkala

私はこれが1年前であることを認識していますが、私は同様の問題を抱えていたのでここにしまいました。私の場合、実際には配列を扱っていました。だから、ここに私の解決策があります。

Handlebars.registerHelper('csv', function(items, options) {
    return options.fn(items.join(', '));
});

// then your template would be
{{#csv list}}{{this}}{{/csv}}

テンプレートにcsvロジックを保持するシンプルでエレガントなソリューションを探していました。

5
freak3dot

Sepブロックヘルパーを作成しました。

Handlebars.registerHelper("sep", function(options){
    if(options.data.last) {
        return options.inverse();
    } else {
        return options.fn();
    }
});

使用法:

{{#each Data}}
   {{Text}}{{#sep}},{{/sep}}
{{/each}}

Elseステートメントをサポートします。

4
Jadro007

ember 2.7を使用すると、ember-truth-helpers

ember install ember-truth-helpers

テンプレートは次のようになります。

{{#each model as |e|}}
    {{e}}{{#unless (eq e model.lastObject)}}, {{/unless}}
{{/each}}
4
albertjan

私はこれを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}}
3
mmacaulay

たぶん、このコンテキストでは、メンバー項目のビューの反復ではなく、コレクションのビューを作成する必要があります。この場合、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}}
2
hellslam