Verwenden von Komma als Listentrennzeichen bei AngularJS


179

Ich muss eine durch Kommas getrennte Liste von Elementen erstellen:

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

Gemäß der AngularJS-Dokumentation sind in Ausdrücken keine Kontrollflussanweisungen zulässig. Deshalb {{$last ? '' : ', '}}funktioniert mein nicht.

Gibt es eine alternative Möglichkeit, durch Kommas getrennte Listen zu erstellen?

EDIT 1
gibt es etwas einfacher als:

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

5
Sie können CSS immer verwenden, um Listen auf diese Weise zu formatieren (dann müssen Sie HTML nicht ändern, wenn Ihr Chef sie in separaten Zeilen usw. haben möchte) - siehe stackoverflow.com/questions/1517220/…
— AlexFoxGill

Antworten:


337

Sie könnten es so machen:

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

..Aber ich mag Philipps Antwort :-)


Sollte nicht ($last && '' || ', ')immer nachgeben ', '?
— Ok,

15
Wie oben, ich konnte keinen Winkel bekommen, um $ last innerhalb einer Vorlage richtig als wahr oder falsch zu bewerten. Ich habe das benutzt : {{{true: '', false: ', '}[$last]}}. Diese Technik ist flexibler als die Verwendung, .joinda die Elemente in der Liste jeweils Mitglieder eines Arrays sein können, z. B.:<b ng-repeat="friend in friends">{{friend.email}}{{{true: '', false: ', '}[$last]}}</b>
— Ryan Marcus,

3
Aktualisiert, um ternäre Operatoren zu verwenden
— Andrew Joslin

1
Wie kann ich und in das gedruckte Array einfügen, damit mein Array so aussieht: John, Mike und Nil. So erhalten Sie dieses Format ohne Verwendung der Direktive.
— MaTya

Ich verwende diesen Ansatz, da ich damit für jeden Wert in der Liste einen Filter verwenden kann.
— C Fairweather

231

Verwenden Sie einfach das integrierte Javascript join(separator) Funktion für Arrays:

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

21
Wenn Sie HTML-ish Separatoren wollen ist es wahrscheinlich Zeit zu einer Schreib Richtlinie . Sie könnten auch HTML in join()HTML
— Philipp Reichart

Schön, ich habe nicht einmal darüber nachgedacht, es so zu benutzen.
— Erdbeere

@ DavidKEgghead Ich bitte um Unterschied, jsfiddle.net/wuZRA . Wie funktioniert das bei dir nicht?
— Philipp Reichart

2
@PhilippReichart Entschuldigung für die Verzögerung. Hier ein Beispiel: jsfiddle.net/Sek8F - Sieht so aus, als würden Sie auf eine Zeichenfolge abzielen, bei der ich mich auf ein Objekt beziehe.
— Ravi Ram

101

Ebenfalls:

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

Und in Vorlage:

{{ itemsArray | joinBy:',' }}

11
Diese Antwort zeigt "Winkelweg" und sollte als die beste markiert werden.
— Eugene Griaznov

14
Warum nicht sechs Zeilen speichern und einfach tun {{ itemsArray.join(', ') }}?
— Philipp Reichart

12
Ich bin nicht sicher, ob das Umschreiben von JavaScript-Kernfunktionen in AngularJS wirklich "der Angular-Weg" ist ...
— Michael Cole

1
Diese Antwort zeigt, wie Angular einen Mehrwert für Arrays von Objekten schaffen kann
— 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
Dies scheint der "semantischste" Weg zu sein, da die Wahl der Verwendung einer durch Kommas getrennten Liste ausschließlich die Präsentation betrifft. Es hätte genauso gut eine Unterliste sein können.
— Elliot Cameron

Dies war die erste Lösung, die mir in den Sinn kam. Weniger abhängig von JavaScript.
— Kalpesh Panchal

10

Sie können auch CSS verwenden, um das Problem zu beheben

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

Aber Andy Joslins Antwort ist am besten

Bearbeiten: Ich habe meine Meinung geändert, dass ich dies kürzlich tun musste, und am Ende habe ich einen Join-Filter verwendet.


2
Ich würde auch für einen benutzerdefinierten Filter gehen, aber ich mag Ihre Idee :)
— JBC

5

Ich denke, es ist besser zu verwenden ng-if. ng-showerstellt ein Element in der domund setzt es display:none. Je mehr domElemente Sie haben, desto ressourcenhungriger wird Ihre App. Auf Geräten mit geringeren Ressourcen gilt: Je weniger Elemente, desto dombesser.

TBH <span ng-if="!$last">, </span>scheint eine großartige Möglichkeit zu sein. Es ist einfach.


Ich mag diesen Ansatz, da er einfach ist und immer noch HTML-basierte Trennzeichen unterstützt. Danke @ the7erm!
— Alexkb

2

Da diese Frage ziemlich alt ist und AngularJS seitdem Zeit hatte, sich weiterzuentwickeln, kann dies jetzt leicht erreicht werden mit:

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

Beachten Sie, dass ich ngBindanstelle der Interpolation verwende, {{ }}da diese viel leistungsfähiger ist: ngBind Wird nur ausgeführt, wenn sich der übergebene Wert tatsächlich ändert. Die Klammern {{ }}hingegen werden bei jedem $ Digest schmutzig überprüft und aktualisiert, auch wenn dies nicht erforderlich ist. Quelle: hier , hier und hier .

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>

Abschließend ist festzuhalten, dass alle hier aufgeführten Lösungen funktionieren und bis heute gültig sind. Ich bin wirklich zu denen gefunden, die CSS betreffen, da dies eher ein Präsentationsproblem ist.


1

Ich mag den Ansatz von simbu, aber es ist mir nicht angenehm, das erste oder letzte Kind zu verwenden. Stattdessen ändere ich nur den Inhalt einer sich wiederholenden Liste-Komma-Klasse.

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

0

Wenn Sie ng-show verwenden, um die Werte zu begrenzen, {{$last ? '' : ', '}}funktioniert dies nicht, da weiterhin alle Werte berücksichtigt werden. Beispiel

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

Das Hinzufügen eines Kommas nach dem "letzten" Wert führt dazu , dass bei ng-show immer noch alle 4 Werte berücksichtigt werden

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

Eine Lösung besteht darin, einen Filter direkt in ng-repeat hinzuzufügen

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

Ergebnisse

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

Gibt es Vorschläge, wie Sie dieses Problem in Angular 2 auf die gleiche Weise lösen können, ohne eine benutzerdefinierte Pipe zu erstellen?
— Chaenu
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.