2012-05-01 6 views
45

私は配列から項目のカンマ区切りリストを生成しようとしているハンドルバーテンプレートを持っています。私のハンドルバーテンプレートで最後の要素の後を除く{{#each}}ループ内の要素間にセパレータを追加するにはどうすればよいですか?

{{#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}} 
+0

もう1つのことは、最後のアイテムを削除すると、次のようになります。最後のセパレータを削除するために、各項目の再描画を強制します。デフォルトでは、アイテムを削除するとそのアイテムのビューのみが削除され、他のアイテムは更新されません(意味があります)。 –

答えて

48

(コメント内の@Jayから):

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

私は最後の子供を見て、IE8ではサポートされていないという事実以外はうまくいくはずです。計算されたプロパティにショットを与えます。区切られたリストを作るための組み込みの方法がないことは、私にはまだ奇妙に思えます。 –

+5

':after'と' last-child'を使うのではなく、 'li + li:before'を使うことで、これを堅固にIE8にすることができます([標準準拠のレンダリングモードにする] //zurb.com/article/284/ie8-rendering-modes-one-meta-tag-to-rule-)!) –

+0

これは完璧です!私はMustache.jsテンプレートでこれを使用していますが、私が交換を探し始めるまでは見つかりませんでした(今は必要ありません)。 –

2

このコンテキストでは、コレクションではなく、メンバーアイテムのビューの反復ではありません。この場合、ハンドルバーイテレータは過剰です。次の例では、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"}); 

以下は、この文脈では動作しませんでした私の元の答えは、です。

あなたはヘルパーでこれを行うことができる必要があります:

li:after { 
    content: ','; 
} 

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

は、私は別のルールを好むが、わずかに少ない場合はより簡潔な:あなたはこれを行うには、標準のCSSを使用することができます

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}} 
+0

残念ながら、これはEmber.jsのデータバインディングと同じように機能しません。 –

+0

計算された属性を試しましたか? – hellslam

+0

私はこれに似たことをしましたが、アイテムごとにHandlebarsテンプレートをサポートするEmber.js ContainerViewと、現在のアイテムが親リストの最後のアイテムかどうかを示す計算されたプロパティを使用しました。私の更新された答えを見てください。これは良いHTMLテンプレート(私がやっているような)を使用する必要がない場合のように見えます。 –

5

私はこれが1年であることを認識していますが、レムとここに巻き込まれている。私の場合、私は実際に配列を扱っていました。だから、私の解決策です。

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

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

私はテンプレートにcsvロジックを保持するシンプルで洗練されたソリューションを検討していました。

55

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

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

最初index値はなります0falseに評価され、追加されることはありません、それ以降のすべての値は、区切り文字を付加しますtrueと評価されます。

+0

これは質問に適合しません。あなたはまだ最後の要素でカンマを取得します... – mk2

+1

@MarcusRennoそれは要素の内容の前に来る。 –

+0

ええ、私は何を考えていたのか分かりません。今度はコードをもう一度読むと完全に意味があります – mk2

3

私はfreak3dotの答えの修正版で、この作業を得た:

(これはノードアプリですので、あなたがブラウザで構築している場合はアンダースコアまたは何でもそれに応じ mapを変更)

handlebars.registerHelper('csv', function(items, options) { 
    return items.map(function(item) { 
    return options.fn(item) 
    }).join(', ') 
}) 

は、各コンマの間でオブジェクトをフォーマットすることができます:

{{#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

私は9月ブロックヘルパーを作成しました:

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

使用法:

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

は、elseステートメントをサポートします。

90

私は部品に遅刻が、私はあなたがember-truth-helpersをインストールした後、あなたがこれを行うことができます残り火2.7でWAYYYY簡単な方法

{{#unless @last}},{{/unless}} 
+8

これは1つです – redben

+14

Emberのハンドルバーを使用している場合は、これは1つではありません。 –

+2

私はEmberを使用していませんが、これを行う方法を探しているときにこのスレッドに出くわしました。ありがとう! –

4

を見つけた知っている:

ember install ember-truth-helpers 

してからテンプレート

{{#each model as |e|}} 
    {{e}}{{#unless (eq e model.lastObject)}}, {{/unless}} 
{{/each}} 
関連する問題