¿Cómo agrego un separador entre elementos en un bucle {{#each}} excepto después del último elemento?


Tengo una plantilla de Manillares donde estoy tratando de generar una lista separada por comas de elementos de una matriz.

En mi plantilla de Manillar:

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

Quiero que el , no aparezca en el último elemento. ¿Hay alguna manera de hacer esto en Handlebars o necesito volver a los selectores CSS?

ACTUALIZACIÓN : Basado en la sugerencia de Christopher, esto es lo que terminé implementando:

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()
    })
}));

Y en mi opinión:

{{collection attachments}}

Y la vista de elementos:

{{content.title}} ({{content.size}}) {{#unless isLastItem}}, {{/unless}}
Author: Chris Thompson, 2012-05-01

8 answers

Puedes usar CSS estándar para hacer esto:

li:after {
    content: ',';
}

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

Prefiero reglas separadas, pero una versión más concisa aunque ligeramente menos legible (de @Jay en los comentarios):

li:not(:last-of-type):after {
    content: ',';
}
 49
Author: Christopher Swasey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-04 17:37:44

Sé que llego tarde a las partes, pero encontré un método WAYYYY más simple

{{#unless @last}},{{/unless}}
 105
Author: MylesBorins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-13 00:04:46

Desde Ember v1.11 puedes obtener el índice de cada uno usando parámetros de bloque. En su caso esto se vería algo como esto:

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

El primer valor index será 0 que evaluará a false y no se agregará, todos los valores posteriores evaluarán a true que precederá a un separador.

 56
Author: Nahkala,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-13 16:56:01

Me doy cuenta de que esto es un año de edad, pero tuve un problema similar y terminó aquí. En mi caso, en realidad estaba tratando con una matriz. Esta es mi solución.

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

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

Iba por una solución simple y elegante que mantiene la lógica csv en la plantilla.

 5
Author: freak3dot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-16 15:34:51

Con ember 2.7 puedes hacer esto después de instalar ember-truth-helpers:

ember install ember-truth-helpers

Y luego su plantilla se verá así:

{{#each model as |e|}}
    {{e}}{{#unless (eq e model.lastObject)}}, {{/unless}}
{{/each}}
 4
Author: albertjan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-16 16:28:51

Tengo esto trabajando con una versión modificada de la respuesta de freak3dot:

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

(Esta es una aplicación de nodo, así que cambie map en consecuencia a subrayado o lo que sea si está compilando en el navegador)

Permite formatear objetos entre cada coma:

{{#csv players}
  {{firstName}} {{lastName}}
{{/csv}}

Editar: Aquí hay una versión más flexible. Unirse a una lista de cosas en un separador arbitrario.

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

Y plantilla:

{{#join players ' vs '}
  {{firstName}} {{lastName}}
{{/join}}
 3
Author: mmacaulay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-23 15:32:20

He creado sep block helper:

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

Uso:

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

Apoya la declaración else.

 3
Author: Jadro007,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-25 12:49:52

Tal vez para este contexto, debería crear una vista para la colección, no una iteración de vistas sobre los elementos miembros. En este caso, un iterador de manillar es excesivo. En mi ejemplo a continuación, los cambios en el FirstName o LastName en los objetos Person se vincularán a la lista y actualizarán la vista.

Plantilla:

{{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"});

A continuación está mi respuesta original, que no funcionó para este contexto.

Usted debe ser capaz de hacer esto con un ayudante:

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
Author: hellslam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-02 17:23:16