Подтвердить что ты не робот

Как добавить разделитель между элементами в цикле {{#each}}, кроме как после последнего элемента?

У меня есть шаблон Handlebars, где я пытаюсь создать список элементов, разделенных запятыми, из массива.

В моем шаблоне Handlebars:

{{#each list}}
    {{name}} {{status}},
{{/each}}

Я хочу, чтобы , не отображался в последнем элементе. Есть ли способ сделать это в Handlebars или мне нужно вернуться к селекторам CSS?

ОБНОВЛЕНИЕ. Основываясь на предложении Кристофера, это то, что я закончил:

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}}
4b9b3361

Ответ 1

Вы можете использовать стандартный CSS для этого:

li:after {
    content: ',';
}

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

Я предпочитаю отдельные правила, но более краткую, если немного менее читаемую версию (от @Jay в комментариях):

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

Ответ 2

Я знаю, что опаздываю на части, но я нашел более простой метод WAYYYY

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

Ответ 3

Так как Ember v1.11 вы можете получить индекс каждого из используемых параметров блока. В вашем случае это будет выглядеть примерно так:

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

Первое значение index будет 0, которое будет оцениваться до false и не будет добавлено, все последующие значения будут оцениваться как true, которые будут добавлять разделитель.

Ответ 4

Я понимаю, что это год, но у меня была аналогичная проблема, и я оказался здесь. В моем случае я действительно имел дело с массивом. Итак, вот мое решение.

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

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

Я собирался для простого и элегантного решения, которое поддерживает логику csv в шаблоне.

Ответ 5

Я создал помощник блока sep:

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

Использование:

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

Поддерживает оператор else.

Ответ 6

С ember 2.7 вы можете сделать это после установки ember-truth-helpers:

ember install ember-truth-helpers

а затем ваш шаблон будет выглядеть так:

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

Ответ 7

Я получил эту работу с измененной версией ответа freak3dot:

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

(Это приложение node, поэтому измените 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}}

Ответ 8

Возможно, для этого контекста вы должны создать представление для коллекции, а не итерацию представлений элементов-членов. В этом случае итератор руля перегружен. В моем примере ниже изменения в firstName или lastName на объектах Person будут привязаны к списку и обновить представление.

Шаблон:

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