在 AngularJS 中为每个第 n 个元素自定义 ng-repeat

Posted

技术标签:

【中文标题】在 AngularJS 中为每个第 n 个元素自定义 ng-repeat【英文标题】:Customize ng-repeat in AngularJS for every nth element 【发布时间】:2014-10-04 15:24:47 【问题描述】:

我正在尝试自定义 ng-repeat 以向每个第 4 个元素添加类似 br 的标签。我试过四处寻找,但似乎找不到可靠的答案。有没有一种简单的方法可以为这样的事情向 Angular 添加条件?我的ng-repeat 只是在其中添加了一些spans 的内容,但我需要每隔第四个元素开始一个新行。

即我想要以下

item1 item2 item3 item4 item5 item6 item7 item8

但现在它只是这样做

item1 item2 item3 item4 item5 item6 item7 item8

如果有任何与ng-repeat 定制相关的好文章(针对新手),我将感谢您提供链接以及迄今为止我发现的所有内容都难以理解。

HTML

  <div class="section">
    <div ng-repeat="items in MyList">
      <img ng-click="AddPoint($index)" src=items.image />
      <span>items.currentPoint/items.endPoint</span>
    </div>
  </div>

【问题讨论】:

【参考方案1】:

您可以只使用$index 并将其与ng-if 一起应用于&lt;br ng-if="!($index%4)" /&gt;

<div class="section">
    <div ng-repeat="items in MyList">
      <img ng-click="AddPoint($index)" src=items.image />
      <span>items.currentPoint/items.endPoint</span>
      <br ng-if="!(($index + 1) % 4)" />
    </div>
  </div>

更新

根据评论,您只需要 css 就可以每隔nth element 清除浮动。

.section > div:nth-of-type(4n+1)
  clear:both;

Demo

如果您担心对旧浏览器的支持,那么只需在特定条件下添加一个类:-

 <div ng-repeat="items in offensiveMasteries" ng-class="wrap:!($index % 4)">

.section &gt; div.wrap 的规则

Demo

【讨论】:

我发誓 AngularJS 是用黑魔法构建的……哈哈,谢谢! @Austin 添加.section &gt; div:nth-of-type(4n+1) clear:both; plnkr.co/edit/wUYKqqP6HtLSnPztHrEL?p=preview @Austin 是的已更新,但您需要担心对旧浏览器的支持 @Austin 这取决于你不能用 css 添加任何元素,但大多数情况下你可以用 css 调整东西。它很强大..您可以使用伪元素等..而不是添加新元素。但这又取决于... 想通了,谢谢大家的帮助!!我刚用.section &gt; div:nth-child(19) visibility:hidden; 【参考方案2】:

我确定您现在已经解决了您的问题。但在未来,为什么不在 javascript 中而不是在前端分隔您的列表。只需进行一些预渲染处理即可得到这样的对象:

// convert this
var list = ["item 1", "item 2", "item 3", "item 4", "item 5", "item 6"];

// into this

var list = [
  ["item 1", "item 2", "item 3"],
  ["item 4", "item 5", "item 6"]
];

// you could use a function like this
function convertToRowsOf3(list) 
  var newList = [];
  var row;
  
  for(var i = 0; i < list.length; i++)
    if(i % 3 == 0) // every 3rd one we're going to start a new row
      if(row instanceof Array)
        newList.push(row); // if the row exists add it to the newList
      
      row = [] // initalize new row
    
    
    row.push(list[i]); // add each item to the row
  
  
  if(row.length > 0) 
    newList.push(row);
  
  
  return newList;
<span ng-repeat="row in list">
  <span ng-repeat="col in row" ng-bind="col"></span><br>
</span>

【讨论】:

这可能是一个有点旧的响应,但我认为移动兼容性可能是一个问题,特别是如果您需要在较小的设备上为两列布局进行一些 CSS 调整大小。跨度> 【参考方案3】:

这就是我实现每 6 个项目插入一行的方式:

<div ng-class='row' ng-if="$index % 6 ? 'row' : ''" ng-repeat="genreNav in genres track by $index">

      <img src="genreNav.image" class="thumbnail img-responsive">

</div>

【讨论】:

【参考方案4】:

PSL 的解决方案是更整洁的解决方案,但是.. 我遇到了同样的问题,最后通过以下方式解决了它(对于那些不想调整 CSS 或不太喜欢它的人)

<div class="row responsive-sm" ng-repeat="exercise in exercises" ng-if="$even">
  <div class="col col-50">
    <div class="item item-stacked-label">
      exercise.title
    </div>
    ....
  </div>
  <div class="col col-50" ng-if="!$last" ng-init="exercise = exercises[$index+1]">
    <div class="item item-stacked-label">
      exercise.title
    </div>
    ....
  </div>
</div>

在这里,我必须每行放置 2 个练习,然后使用 ng-init 将每个副本上实际选择的一个(练习)再次设置为下一个($index+1)。注意 ng-if 中的 !$last,没有输出可能会损坏页面,因为数组中没有更多元素要显示

【讨论】:

以上是关于在 AngularJS 中为每个第 n 个元素自定义 ng-repeat的主要内容,如果未能解决你的问题,请参考以下文章

6-11 求自定类型元素序列的中位数(25 分)

angularjs在不同文件中为同一个模块定义服务

4-4 求自定类型元素的平均

4-5 求自定类型元素的最大值

4-4 求自定类型元素的平均 (10分)

4-11 求自定类型元素序列的中位数 (25分)