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.