使用逗号作为AngularJS的列表分隔符

181

我需要创建一个逗号分隔的项目列表:

  <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)- 请参见https://dev59.com/2nI_5IYBdhLWcg3wHvQ5 - Alex
9个回答

342
你可以这样做: {{email}}{{$last ? '' : ', '}} ..不过我喜欢Philipp的答案 :-)

($last && '' || ', ') 不应该总是生成 ', ' 吗? - okm
15
像上面的 okm 一样,我无法让 Angular 在模板中正确地将 $last 评估为 true 或 false。我使用了这个:{{{true: '', false: ', '}[$last]}}。这种技术比使用.join更灵活,因为它允许列表中的元素都成为数组的成员,例如:<b ng-repeat="friend in friends">{{friend.email}}{{{true: '', false: ', '}[$last]}}</b> - Ryan Marcus
3
已更新以使用三元运算符。 - Andrew Joslin
1
我该如何在打印的数组中插入“和”字,使得我的数组看起来像这样:John、Mike 和 Nil。如何在不使用指令的情况下获得这种格式。 - MaTya
我使用这种方法,因为它允许我在列表中的每个值上使用过滤器。 - C Fairweather
我喜欢这个,因为它在迭代对象方面表现出色...谢谢您的建议! - Billy McCafferty

232
只需使用JavaScript内置的 join(separator) 函数即可将数组连成字符串。
<li ng-repeat="friend in friends">
  <b>{{friend.email.join(', ')}}</b>...
</li>

21
如果你想要类似HTML的分隔符,那现在可能是写一个指令的时候了(参考链接:http://docs.angularjs.org/guide/directive)。你也可以将HTML放入`join()`中并禁用HTML转义,但是这样做会有特别的后果。 - Philipp Reichart
很好,我甚至没有想过可以这样使用它。 - Strawberry
@DavidKEgghead 我不同意,http://jsfiddle.net/wuZRA/。它为什么对你不起作用呢? - Philipp Reichart
2
@PhilippReichart 抱歉耽搁了。这里有一个例子:http://jsfiddle.net/Sek8F/ -- 看起来你是在针对一个字符串,而我是在引用一个对象。 - Ravi Ram

101

此外:

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

并且在模板中:

{{ itemsArray | joinBy:',' }}

11
此答案展示了“Angular的方式”,应该被标记为最佳答案。 - Eugene
14
为什么不简化为{{ itemsArray.join(', ') }}并节省六行代码呢? - Philipp Reichart
12
我不确定在AngularJS中重写JavaScript核心函数是否真的符合“Angular方式”... - Michael Cole
1
这篇回答展示了Angular如何为对象数组增加价值。 - Michael Cole

42

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


1
这似乎是最“语义化”的方式,因为使用逗号分隔列表的选择完全是关于呈现。它也可以是子列表。 - Elliot Cameron
这是我想到的第一个解决方案。不太依赖 JavaScript。 - Kalpesh Panchal

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

但是Andy Joslin的回答是最好的。

编辑:我改变了主意,最近我不得不这样做,最终选择使用了join过滤器。


2
我也会选择自定义过滤器,但我喜欢您的想法 :) - JBC

5

我认为最好使用ng-ifng-show会在dom中创建一个元素并将其设置为display:none。你的应用程序中有越多的dom元素,它就会更加占用资源,在低资源设备上,dom元素越少越好。

说实话,<span ng-if="!$last">, </span>看起来像是一种很好的方法。 这很简单。


我喜欢这种方法,因为它简单并且仍支持基于HTML的分隔符。谢谢@the7erm! - alexkb

3

由于这个问题已经很老了,AngularJS也有了时间来演变,现在可以使用以下方法轻松实现:

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

请注意,我使用的是 ngBind 而不是插值表达式 {{ }},因为它的性能更好:只有当传递的值实际上发生了变化时,ngBind 才会运行。另一方面,即使不必要,括号{{ }}也会被脏检查并在每个 $digest 中刷新。来源:这里这里这里

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的方法,但是我不太舒服使用first-child或last-child。相反,我只修改重复列表逗号类的内容。

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

在“last”值后添加逗号的结果, 因为使用ng-show时它仍会考虑所有4个值

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

一种解决方案是直接将过滤器添加到ng-repeat中

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

结果

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

有没有建议如何在Angular 2中解决这个问题,而不需要创建自定义管道? - chaenu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接