【问题标题】:How to split ng-repeat into batches如何将 ng-repeat 拆分为批次
【发布时间】:2014-04-20 21:07:12
【问题描述】:

我在 http://getbootstrap.com/javascript/#buttons-examples 做这个 ref:checkbox 示例

<div class="btn-group list-group-item-text" data-toggle="buttons">
  <label data-ng-repeat="type in types"
         ng-class="{btn: true, 'btn-primary': true, active: Map[type.id]}">
    <input type="checkbox" ng-model="Map[type.id]">{{type.name}}
  </label>
</div>

现在的问题是有时这个类型数组的项目少于 5 个,有时更多。当按钮组有超过 5 个项目时,它会以一种丑陋的方式拆分到下一行。

我该怎么做这样的事情

ng-repeat on 0-4 of array - create a button group for these 5 items
ng-repeat on 5-9 of array (if array length is >5) ...
ng-repeat on 10-14 of array (if array length is >10) ...
...

注意:更好的是查看使用了多少个字符。每种类型都有不同的名称,有些长有些短,所以有时一个很长的名称会占用面板的所有宽度。

【问题讨论】:

    标签: javascript css angularjs


    【解决方案1】:

    ng-repeat 使用两个 limitTo 过滤器,具有正值和负值。

    http://docs.angularjs.org/api/ng/filter/limitTo

    这是一个演示http://plnkr.co/edit/8LXXnH?p=preview

    更新示例:

    <li ng-repeat="item in items | limitTo: 5 | limitTo: -5">{{item}}</li>
    <li ng-repeat="item in items | limitTo: 10 | limitTo: -5">{{item}}</li>
    

    第一个 ng-repeat 将返回数组的 0 到 4,第二个 ng-repeat 将返回 5 到 9。

    【讨论】:

    • 聪明,但有一个小错误:当数组不能被“限制大小”整除时,它不会按预期工作。在这种情况下,如果您的 items 数组有 9 个项目,则 item[4] 将显示在第一个列表的末尾和第二个列表的开头。
    • 为了解决这个问题,我最后一批使用了以下逻辑:item in items | limitTo:15 | limitTo:items.length % 5 * -1,使用模除法来确定负限制应该有多大。
    【解决方案2】:

    您可以将它们预先分组,然后使用嵌套中继器。

    var groups = [],
        maxGroupSize = 4,
        groupNum = 0;
    
    groups.push([]);
    groupNum = 0;
    
    for (var i = 0; i < types.length; i++) {
      groups[groupNum].push(types[i]);
    
      if (groups[groupNum].length === maxGroupSize) {
          groups.push([]);
          groupNum++;
      }
    }
    
    
    
    $scope.groups = groups;
    

    然后你可以像这样使用嵌套中继器:

    <div data-ng-repeat="group in groups"
       class="btn-group list-group-item-text" data-toggle="buttons">
         <label data-ng-repeat="type in group"
                ng-class="{btn: true, 'btn-primary': true, active: Map[type.id]}">
             <input type="checkbox" ng-model="Map[type.id]">{{type.name}}
         </label>
    </div>
    

    这里有一个 jsFiddle 示例来演示:http://jsfiddle.net/jwcarroll/V8fuy/

    更新:

    我创建了一个updated version of the same fiddle 来显示使用一点 CSS 来截断带有省略号的文本。通过添加title 属性,您可以获得默认的工具提示功能,但最好使用Bootstrap Tooltip plugin

    您可能需要创建一个指令或使用类似Angular Bootstrap 的东西。

    【讨论】:

    • 我想指出,在这个解决方案中,分组发生在 $scope 分配之前,这是正确的方法。您不希望将范围变量放在循环中。
    • @AlexC:这也不能解决问题:Every type has different name, some long some short, so some times a really long name can use up all the width of the panel。只需一个简单的 css 就可以了,不需要使用分组。
    • @KhanhTO 哦,对不起,我没有仔细阅读上下文。是的,CSS 修复更好。
    • @KhanhTO - 通常我会同意你的看法,但在这种特殊情况下,他使用了一个非常具体的 Bootstrap 构造,它基本上已经在使用你提到的“CSS”技巧。问题是,从视觉上看,如果它变得太宽,该组就会被破坏。这可以通过通过 CSS 用省略号截断文本以使其保持特定宽度,然后添加工具提示来缓解。
    • 如果我们控制specific width,我们根本不需要分组,因为我们可以控制行宽和项目的宽度,它会自动很好地换行到下一行。问题是名称宽度不同。如果用户调整窗口大小怎么办?
    【解决方案3】:

    我还没有测试过,但我想你可以用 splice 硬编码限制:

    <div data-ng-repeat="group1Item in items.splice(limit1,limit2-limit1)"> ... </div>
    <div data-ng-repeat="group2Item in items.splice(limit2,limit3-limit2)"> ... </div>
    <div data-ng-repeat="group3Item in items.splice(limit3,limit4-limit3)"> ... </div>
    

    这对于相对较小的数组来说很好,但我认为预分组是用于较大数组的方法。

    【讨论】:

      【解决方案4】:

      如果您不介意使用库,这正是lodash#chunk 所做的。 在你的控制器中进行分块,然后在你的视图中编写一个嵌套的 for 循环。

      创建一个元素数组,该数组被分成大小长度的组。如果集合不能被平均分割,最后的块将是剩余的元素。

      _.chunk(['a', 'b', 'c', 'd'], 2);
      // → [['a', 'b'], ['c', 'd']]
      
      _.chunk(['a', 'b', 'c', 'd'], 3);
      // → [['a', 'b', 'c'], ['d']]
      

      【讨论】:

        猜你喜欢
        • 2020-07-16
        • 2018-04-26
        • 2014-11-25
        • 2014-03-05
        • 2017-05-06
        • 1970-01-01
        • 2023-03-31
        • 2017-06-16
        相关资源
        最近更新 更多