【问题标题】:AngularJS ng-repeat to populate grid from arrayAngularJS ng-repeat 从数组填充网格
【发布时间】:2015-03-19 09:35:24
【问题描述】:

提前感谢您的阅读。我正在尝试利用 Angular 的 ng-repeat 将数组中的对象渲染到 Nx3 表中。为了举例,让我们考虑一个 3x3 的表格。

这里是一个简化的数组示例:

objects = [{"text": "One, One"},{"text": "One, Two"},{"text": "One, Three"},
           {"text": "Two, One"},{"text": "Two, Two"},{"text": "Two, Three"},
           {"text": "Three, One"},{"text": "Three, Two"},{"text": "Three, Three"}];

“文本”字段描述了每个元素应出现在 3x3 网格矩阵中的哪个位置。我想在 objects 上使用 ng-repeat 来生成如下所示的 html:

<table>
  <tr>
    <td>One, One</td>
    <td>One, Two</td>
    <td>One, Three</td>
  </tr>
  <tr>
    <td>Two, One</td>
    <td>Two, Two</td>
    <td>Two, Three</td>
  </tr>
  <tr>
    <td>Three, One</td>
    <td>Three, Two</td>
    <td>Three, Three</td>
  </tr>
</table>

有没有什么方法可以实现这一点,而无需将数组分解为每一行的单独数组?

【问题讨论】:

  • 这篇文章或许对你有帮助:stackoverflow.com/questions/15973985/…
  • 你好 Cumulo,你是想列出三三两两还是其他的东西?
  • 感谢@arman1991 的参考,但该示例使用多个数组,每行一个;我只想对多行使用一个数组。 katmanco 实际文本无关紧要,我只是想传达每个“文本”字符串对象应该去哪里的想法
  • @PSL 是的!如果您可以发布该答案并在您所做的事情背后稍作解释,我将很乐意接受。谢谢!

标签: arrays angularjs html-table ng-repeat


【解决方案1】:

最好的方法是在控制器中更改您的视图模型并将其绑定到 ng-repeat(但您已经说过您不想这样做)。如果您打算走这条路,您还可以查看用户@m59 answer,他创建了一个可重复使用的过滤器来执行此操作。然而,这只是一个简单的答案,利用内置过滤器的可配置评估表达式,我们可以返回真/假值以确定它们是否需要重复。这最终具有不需要创建 2 个 ng-repeat 块的唯一优势(但这并不是那么糟糕)。因此,在您的控制器中,在作用域上添加一个函数,

$scope.getFiltered= function(obj, idx){
   //Set a property on the item being repeated with its actual index
   //return true only for every 1st item in 3 items
    return !((obj._index = idx) % 3); 
}

并在您看来应用过滤器:

  <tr ng-repeat="obj in objects | filter:getFiltered">
    <!-- Current item, i.e first of every third item -->
    <td>{{obj.text}}</td> 
    <!-- based on the _index property display the next 2 items (which have been already filtered out) -->
    <td>{{objects[obj._index+1].text}}</td>
    <td>{{objects[obj._index+2].text}}</td>
  </tr>

Plnkr

【讨论】:

  • 感谢您提供明确的解决方案。我很想知道为什么“最可靠和技术上正确的方法是转换控制器中的数据”而不是使用像这里实现的过滤方法。只要在 ng-repeat 中避免 ,这种过滤方法似乎与其他方法等效(如果不干净的话)。
  • 一个主要原因是性能,当您在视图中添加过滤器时,它总是很昂贵,因为过滤器每个摘要周期至少运行两次,如果您在过滤器中转换数据,他们会想象您正在这样做每个消化周期。另一件事是在进行单元测试时通常很难对视图进行测试,因此对控制器进行测试总是比对视图容易。另一件事是您无需猜测数据在何处以及如何转换,因为您已经在控制器中进行了转换,并且非常直接且可见。
  • 这有很多原因哈哈,而且完全有道理。谢谢
【解决方案2】:

我想做同样的事情。

将数组转换为矩阵/网格

我有一个数组,我想将其转换为列大小为 4 的网格/矩阵。以下实现对我有用。您可以在嵌套的 ng-repeat 中随意使用两个计数器: row 和 col

在我的例子中,列数是 3。但是你可以在任何地方用一个变量替换那个 3。 h.seats 是我的对象数组,我想打印 X 或 - 基于该数组中元素的值

<div class="table-responsive">
    <table class="table table-bordered">
        <thead>
            <tr>
                <th ng-repeat="n in [].constructor(3 + 1) track by $index">{{$index}}</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="(row, y) in getNumber(h.seats.length, 3) track by $index">
                <td>{{row+1}}</td>
                <td class="text-primary"
                    ng-repeat="(col, t) in h.seats track by $index"
                    ng-if="col >= (row)*3 && col < (row+1)*3">
                        <span ng-show="t.status"> X </span> 
                        <span ng-show="!t.status"> - </span>
                </td>
            </tr>
        </tbody>
    </table>
</div>

&lt;th ng-repeat="n in [].constructor(3 + 1) track by $index"&gt;{{$index}}&lt;/th&gt; 在顶部打印列号的标题行。 getNumber(h.seats.length, 3) 返回该表的行数,如下所示

.controller('CustomViewController', function ($scope, Principal, $state) {

    $scope.getNumber = function(length, columns) {
        return new Array(parseInt(length / columns + 1, 10));   
    }

ng-if="col &gt;= (row)*3 &amp;&amp; col &lt; (row+1)*3" 行是计算应该在该行中放入哪些元素的重要逻辑。 输出如下所示

0  1  2  3 
1  e1 e2 e3 
2  e4 e5 e6 
3  e7 e8 

有关如何使用行和列计数器的详细信息,请参阅以下链接: https://stackoverflow.com/a/35566132/5076414

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 1970-01-01
    • 2014-06-18
    • 1970-01-01
    • 2015-10-23
    • 2023-03-25
    • 1970-01-01
    相关资源
    最近更新 更多