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.