【问题标题】:How to build a table with ng-repeat with mixed number of columns for row?如何使用 ng-repeat 构建一个表,其中行的列数是混合的?
【发布时间】:2014-06-06 23:26:18
【问题描述】:

我真的不知道如何简洁地描述我正在尝试做的事情,所以对于糟糕的标题感到抱歉。但是我有一张表,我想在其中交错不同类型的行。我有一行反映顶部的列,还有另一行跨越所有列以显示年份。

例如:

<table>
  <thead>...</thead>
  <tbody>
     <tr>
         <td>11/30/2013</td>
         <td>Some Description</td>
         <td>$1450.00</td>
         ...
     </tr>
     <tr>
         <td>12/31/2013</td>
         <td>Some Description</td>
         <td>$1450.00</td>
         ...
     </tr>
     <tr colspan="9">2014</tr>
     <tr>
         <td>1/31/2014</td>
         <td>Some Description</td>
         <td>$1450.00</td>
         ...
     </tr>
   </tbody>
</table>

这是将所有数据放入表中的简单实现:

<table>
  <thead>...</thead>
  <tbody>
      <tr ng-repeat="paycheck in paychecks">
         <td>{{paycheck.payDate}}</td>
         <td>{{paycheck.description}}</td>
         <td>{{paycheck.amount}}</td>
         ...
      </tr>
  </tbody>
</table>

但是,当我遍历年度边界时,我想将这一行放在这些行之间:

<tr>
   <td colspan="9" ng-if="paycheck.payDate.year > previousPaycheck.payDate.year">{{paycheck.payDate.year}}</td>
</tr>

这意味着当上述条件为真时,我必须在表中添加两行,但使用 ng-repeat 我只添加一个。我怀疑我必须重建我的数据结构,以便在其中插入年份边界,因此 ng-repeat 将是 1:1,表中的行和数组中的元素。或者也许一些特殊的指令魔法可以让这更容易。

有没有我看不到的简单方法?

【问题讨论】:

  • 您能否发布一些工资单对象的示例数据
  • paychecks 中的数据对答案并不重要,因为它是一堆属性(其中一个是上图所示的日期),并且这些属性放在每一行的一系列列中.我在示例中包含了足够多的属性供您猜测数据的样子。

标签: angularjs angularjs-ng-repeat


【解决方案1】:

您可以使用ng-repeat-startng-repeat-end

<tbody>
      <tr ng-repeat-start="paycheck in paychecks">
        <td colspan="9" ng-if="paycheck.payDate.year > paychecks[$index-1].payDate.year">  {{paycheck.payDate.year}}</td>
      </tr>
      <tr ng-repeat-end>
         <td>{{paycheck.payDate}}</td>
         <td>{{paycheck.description}}</td>
         <td>{{paycheck.amount}}</td>
      </tr>          
</tbody>

Plunker

【讨论】:

    【解决方案2】:

    ng-repeat 有一些变量在每次迭代时附加到作用域,一个是 $index

    利用这一点,您可以执行以下操作:

    <table>
        <tbody ng-repeat="date in data">
          <tr ng-show='$index == 0 || data[$index].year != data[$index-1].year'>
            <td colspan="3">{{date.year}}</td>
          </tr>
          <tr>
            <td>{{date.year}}</td>
            <td>{{date.month}}</td>
            <td>{{date.day}}</td>
          </tr>
        </tbody>
    </table>
    

    Plunker:http://plnkr.co/edit/axuKJTuTii1v8M4cX5Dk

    请注意,这需要对您的数据进行排序。

    【讨论】:

    • 这将为您的每个薪水提供一个单独的tbody,这可能不是您想要的。
    • 与解决方案无关的小细节。
    • 如果你有 css 样式表不需要多个 tbody 标签,这无关紧要。
    • 我只是建议提问者看看逻辑,而不是将解决方案复制/粘贴到他自己的工作中。
    • 也许提问者实际上想要 表中有多个组,在这种情况下,这种方法更可取。但他想要的输出只显示一个tbody
    【解决方案3】:

    有趣的问题。

    这是 plunker 中的一个有效解决方案:http://plnkr.co/edit/a55krX8x9G1e5MGUIz0A?p=preview

    逻辑: 首先,数据必须按payDate 排序才能正常工作

       <tbody ng-repeat="paycheck in paychecksOrdered">
          <tr ng-show="header(paycheck, $index)">
            <td colspan="9">{{paycheck.payDate | date:'yyyy'}}</td>
          </tr>
          <tr>
            <td>{{paycheck.payDate}}</td>
            <td>{{paycheck.description}}</td>
            <td>{{paycheck.amount}}</td>
          </tr>
        </tbody>
    
    
    
      $scope.paychecksOrdered = $filter('date')(paychecks, 'payDate');
      $scope.header = function(paycheck, i) {
        if (i === 0) {
          return true;
        }
        console.log(i);
        var past = $scope.paychecksOrdered[i - 1].payDate.getFullYear(),
          cur = paycheck.payDate.getFullYear();
        console.log(cur, past);
        return past != cur;
      };
    

    【讨论】:

    • 与其他答案一样,这将为您提供每个薪水的单独 tbody,这可能不是您想要的。
    • 在 tbody 上使用 ng-repeat 似乎是有效的,请参阅这篇文章 -stackoverflow.com/questions/3076708/…
    • 并不是说它无效,只是说您最终可能会得到一个您不期望的表格。
    • 我可以明智地使用 ng-repeat 或使用开始/结束标签。这只是问题的解决方案。甚至 html 验证器也允许一个表中有多个 tbody 元素。虽然我不确定这将如何导致意外的表。我想在这里应用 CSS 将是微不足道的。
    • 为什么要用不必要的标签填充 DOM?
    猜你喜欢
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-07
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    相关资源
    最近更新 更多