Usando una coma como separador de lista con AngularJS


179

Necesito crear una lista de elementos separados por comas:

  <li ng-repeat="friend in friends">
      <b ng-repeat="email in friend.email">{{email}}{{$last ? '' : ', '}}</b>...
  </li>

De acuerdo con la documentación de AngularJS, no se permiten declaraciones de flujo de control en las expresiones. Por eso mi{{$last ? '' : ', '}} no funciona.

¿Hay alguna forma alternativa de crear listas separadas por comas?

EDITAR 1
¿hay algo más simple que:

<span ng-show="!$last">, </span>

55
Siempre puede usar CSS para formatear listas de esta manera (entonces no necesita modificar HTML cuando su jefe las quiere en líneas separadas, etc.) - consulte stackoverflow.com/questions/1517220/…
— AlexFoxGill

Respuestas:


338

Podrías hacerlo de esta manera:

<b ng-repeat="email in friend.email">{{email}}{{$last ? '' : ', '}}</b>

..Pero me gusta la respuesta de Philipp :-)


¿No debería ($last && '' || ', ')ceder siempre ', '?
— okm

15
Al igual que arriba, no pude ser angular para evaluar adecuadamente $ last a verdadero o falso dentro de una plantilla. He utilizado este: {{{true: '', false: ', '}[$last]}}. Esta técnica es más flexible que el uso .joinporque permite que los elementos de la lista sean miembros de una matriz, como:<b ng-repeat="friend in friends">{{friend.email}}{{{true: '', false: ', '}[$last]}}</b>
— Ryan Marcus

3
Actualizado para usar operadores ternarios
— Andrew Joslin

1
¿Cómo puedo insertar y en la matriz impresa para que mi matriz se vea así: John, Mike y Nil. Cómo obtener este formato sin usar la directiva.
— MaTya

Estoy usando este enfoque ya que me permite usar un filtro en cada valor de la lista.
— C Fairweather

231

Simplemente use la función incorporada de Javascript join(separator)para las matrices:

<li ng-repeat="friend in friends">
  <b>{{friend.email.join(', ')}}</b>...
</li>

21
Si desea separadores HTML-ish, probablemente sea hora de escribir una directiva . También podría poner HTML join()y deshabilitar el escape de HTML, pero hay un lugar especial en el infierno para eso;)
— Philipp Reichart

Bien, ni siquiera pensé en usarlo de esta manera.
— Fresa

@DavidKEgghead Ruego diferir, jsfiddle.net/wuZRA . ¿Cómo no te funciona?
— Philipp Reichart

2
@PhilippReichart perdón por la demora. Aquí hay un ejemplo: jsfiddle.net/Sek8F : parece que está apuntando a una cadena donde me estoy refiriendo a un objeto.
— Ravi Ram

101

También:

angular.module('App.filters', [])
    .filter('joinBy', function () {
        return function (input,delimiter) {
            return (input || []).join(delimiter || ',');
        };
    });

Y en plantilla:

{{ itemsArray | joinBy:',' }}

11
Esta respuesta muestra "forma angular" y debe marcarse como la mejor.
— Eugene Griaznov

14
¿Por qué no guardar seis líneas y simplemente hacer {{ itemsArray.join(', ') }}?
— Philipp Reichart

12
No estoy seguro de reescribir las funciones básicas de JavaScript en AngularJS es realmente "la forma angular" ...
— Michael Cole

1
Esta respuesta muestra cómo Angular puede agregar valor para las matrices de objetos
— Michael Cole

41

.list-comma::before {
  content: ',';
}
.list-comma:first-child::before {
  content: '';
}
<span class="list-comma" ng-repeat="destination in destinations">
                            {{destination.name}}
                        </span>


1
Esto parece ser la forma más "semántica", ya que la elección de usar una lista separada por comas es totalmente sobre la presentación. También podría haber sido una sublista.
— Elliot Cameron

Esta fue la primera solución que vino a mi mente. Menos dependiente de JavaScript.
— Kalpesh Panchal

10

Puedes usar CSS para arreglarlo también

<div class="some-container">
[ <span ng-repeat="something in somethings">{{something}}<span class="list-comma">, </span></span> ]
</div>

.some-container span:last-child .list-comma{
    display: none;
}

Pero la respuesta de Andy Joslin es la mejor

Editar: cambié de opinión, tenía que hacer esto recientemente y terminé con un filtro de combinación.


2
También elegiría un filtro personalizado, pero me gusta tu idea :)
— JBC

5

Creo que es mejor usarlo ng-if. ng-showcrea un elemento en domy lo establece display:none. Cuantos más domelementos tenga, más recursos necesitará su aplicación, y en dispositivos con menos recursos, menosdom elementos, mejor.

TBH <span ng-if="!$last">, </span>parece ser una excelente manera de hacerlo. Es sencillo.


Me gusta este enfoque, ya que es simple y aún admite separadores basados ​​en html. Gracias @ the7erm!
— alexkb

2

Como esta pregunta es bastante antigua y AngularJS ha tenido tiempo de evolucionar desde entonces, ahora se puede lograr fácilmente usando:

<li ng-repeat="record in records" ng-bind="record + ($last ? '' : ', ')"></li>.

Tenga en cuenta que estoy usando en ngBindlugar de la interpolación, {{ }}ya que es mucho más eficiente: ngBind solo se ejecutará cuando el valor pasado realmente cambie. Los corchetes {{ }}, por otro lado, serán revisados ​​y actualizados en cada $ digest, incluso si no es necesario. Fuente: aquí , aquí y aquí .

angular
  .module('myApp', [])
  .controller('MyCtrl', ['$scope',
    function($scope) {
      $scope.records = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    }
  ]);
li {
  display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
  <ul>
    <li ng-repeat="record in records" ng-bind="record + ($last ? '' : ', ')"></li>
  </ul>
</div>

En una nota final, todas las soluciones aquí funcionan y son válidas hasta el día de hoy. Realmente me encuentro con aquellos que involucran CSS ya que esto es más un problema de presentación.


1

Me gusta el enfoque de simbu, pero no me siento cómodo con el primer hijo o el último hijo. En cambio, solo modifico el contenido de una clase repetida de lista-coma.

.list-comma + .list-comma::before {
    content: ', ';
}
<span class="list-comma" ng-repeat="destination in destinations">
    {{destination.name}}
</span>

0

Si está utilizando ng-show para limitar los valores, {{$last ? '' : ', '}}no funcionará, ya que aún tendrá en cuenta todos los valores.

<div ng-repeat="x in records" ng-show="x.email == 1">{{x}}{{$last ? '' : ', '}}</div>

var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function($scope) {
  $scope.records = [
    {"email": "1"},
    {"email": "1"},
    {"email": "2"},
    {"email": "3"}
  ]
});

Resulta en agregar una coma después del "último" valor , ya que con ng-show todavía tiene en cuenta los 4 valores

{"email":"1"},
{"email":"1"},

Una solución es agregar un filtro directamente en ng-repeat

<div ng-repeat="x in records | filter: { email : '1' } ">{{x}}{{$last ? '' : ', '}}</div>

Resultados

{"email":"1"},
{"email":"1"}

¿Alguna sugerencia sobre cómo resolver este problema de la misma manera en Angular 2 sin crear una tubería personalizada?
— chaenu
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.