Використання кома як роздільника списку за допомогою AngularJS


179

Мені потрібно створити розділений комою список елементів:

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

Згідно з документацією AngularJS, жодні оператори управління потоком не дозволяються у виразах. Ось чому мій {{$last ? '' : ', '}}не працює.

Чи існує альтернативний спосіб створення списків, розділених комами?

EDIT 1
є щось простіше, ніж:

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

5
Ви завжди можете використовувати CSS для форматування списків таким чином (то вам не потрібно змінювати HTML , коли ваш бос хоче , щоб їх на окремі рядки і т.д.) - див stackoverflow.com/questions/1517220 / ...
AlexFoxGill

Відповіді:


338

Ви можете це зробити так:

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

..Але мені подобається відповідь Філіпа :-)


Не ($last && '' || ', ')завжди слід поступатися ', '?
окм

15
Як і вище, я не можу отримати кутовий, щоб правильно оцінити $ last to true або false у шаблоні. Я використовував це: {{{true: '', false: ', '}[$last]}}. Цей прийом є більш гнучким, ніж використання, .joinоскільки він дозволяє елементам у списку бути членами масиву, наприклад:<b ng-repeat="friend in friends">{{friend.email}}{{{true: '', false: ', '}[$last]}}</b>
Райан Маркус

3
Оновлено для використання потрійних операторів
Ендрю Джослін

1
Як я можу вставити і в друкований масив, щоб мій масив виглядав так: Джон, Майк та Ніл. Як отримати цей формат без використання директиви.
Матя

Я використовую цей підхід, оскільки він дозволяє мені використовувати фільтр для кожного значення у списку.
C Fairweather

231

Просто використовуйте вбудовану join(separator)функцію Javascript для масивів:

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

21
Якщо ви хочете розділити HTML-ish, напевно, настав час написати директиву . Ви також можете ввести HTML join()і відключити відхід від HTML, але для цього є певне місце в пеклі;)
Philipp Reichart

Приємно, я навіть не думав використовувати це таким чином.
Полуниця

@DavidKEgghead Я прошу відрізнятись, jsfiddle.net/wuZRA . Як це не працює для вас?
Філіп Рейхарт

2
@PhilippReichart вибачте за затримку. Ось приклад: jsfiddle.net/Sek8F - схоже на те, що ви націлюєте рядок, де, як я маю на увазі об'єкт.
Раві Рам

101

Також:

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

І в шаблоні:

{{ itemsArray | joinBy:',' }}

11
Ця відповідь показує «кутовий шлях» і повинна бути відзначена як найкраща.
Євген Гріазнов

14
Чому б не зберегти шість рядків і просто зробити {{ itemsArray.join(', ') }}?
Філіп Рейхарт

12
Я не впевнений, що переписування основних функцій JavaScript в AngularJS насправді є "кутовим способом" ...
Майкл Коул

1
Ця відповідь показує, як Angular може додати значення для масивів об’єктів
Майкл Коул

41

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


1
Це здається найбільш "семантичним" способом, оскільки вибір використання списку, розділеного комами, повністю стосується презентації. Це також могло бути підписом.
Елліот Кемерон

Це було перше рішення, яке прийшло мені в голову. Менш покладається на JavaScript.
Калпеш Панчал

10

Ви можете також використовувати CSS, щоб виправити його

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

Але відповідь Енді Джосліна найкраща

Редагувати: Я передумав, що мені довелося це зробити нещодавно, і я закінчив роботу з фільтром приєднання.


2
Я б також пішов на спеціальний фільтр, але мені подобається ваша ідея :)
JBC

5

Я думаю, що краще використовувати ng-if. ng-showстворює елемент в domі встановлює його display:none. Чим більше domелементів у вас більше, тим голоднішим стає ваш додаток, а на пристроях із меншими ресурсами - тим менше domелементів.

ТББ <span ng-if="!$last">, </span>здається чудовим способом це зробити. Це просто.


Мені подобається такий підхід, оскільки він простий і все ще підтримує розділені на html роздільники. Дякую @ the7erm!
alexkb

2

Оскільки це питання досить давнє і AngularJS встиг розвинутися з тих пір, цього можна легко досягти, використовуючи:

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

Зауважте, що я використовую ngBindзамість інтерполяції, {{ }}оскільки це набагато ефективніше: ngBind працюватиме лише тоді, коли передане значення дійсно зміниться. З {{ }}іншого боку, дужки будуть перевірені та оновлені в кожному дайджесті $, навіть якщо це не потрібно. Джерело: тут , тут і тут .

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>

На завершення всі рішення тут працюють і діють донині. Я дійсно знайшов тих, хто стосується CSS, оскільки це більше питання презентації.


1

Мені подобається підхід simbu, але мені не зручно користуватися першою дитиною або останньою дитиною. Натомість я лише змінюю вміст повторюваного класу список-кома.

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

0

Якщо ви використовуєте ng-show для обмеження значень, {{$last ? '' : ', '}}виграш не буде, оскільки він все одно врахує всі значення. Приклад

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

Результати додавання коми після "останнього" значення , оскільки при ng-show він все-таки враховує всі 4 значення

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

Одне рішення - додати фільтр безпосередньо в ng-повтор

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

Результати

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

Будь-яка пропозиція, як вирішити цю проблему так само в Angular 2, не створюючи спеціальної труби?
chaenu
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.