用ng重复填充表,并检查匹配的表头数据

Populate table with ng-repeat and check matching header data

本文关键字:检查 数据 表头 ng 填充      更新时间:2024-05-11

我有一个年份数组,用于填充表头行,还有一个对象用于填充表。我需要在相应的年份标题下填充正确的年份数据,因此我需要检查对象中的年份(Y)是否与标题数组中的年份对应,如果不对应,则我需要添加一个空单元格。对象按年份排序。最好的方法是什么?这是小提琴

控制器

 var app = angular.module("testModule", []);
 app.controller('testController', function($scope) {
 $scope.headerYears = [2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020];
$scope.rows = [{
  "Name": "Name1",
  "Col": [{
    "Y": 2013,
    "M": 25711
  }, {
    "Y": 2014,
    "M": 26095
  }, {
    "Y": 2015,
    "M": 23641
  }, {
    "Y": 2016,
    "M": 22224
  }, {
    "Y": 2017,
    "M": 21968
  }, {
    "Y": 2018,
    "M": 23820
  }, {
    "Y": 2019,
    "M": 26673
  }, {
    "Y": 2020,
    "M": 29329.5
  }]
}, {
  "Name": "Name2",
  "Col": [{
    "Y": 2013,
    "M": 83
  }, {
    "Y": 2014,
    "M": 461
  }, {
    "Y": 2015,
    "M": 1067
  }, {
    "Y": 2016,
    "M": 1120
  }, {
    "Y": 2017,
    "M": 1050
  }, {
    "Y": 2018,
    "M": 600
  }, {
    "Y": 2019,
    "M": 475
  }, {
    "Y": 2020,
    "M": 481
  }]
}, {
  "Name": "Name3",
  "Col": [{
    "Y": 2013,
    "M": 25794
  }, {
    "Y": 2014,
    "M": 26556
  }, {
    "Y": 2015,
    "M": 24708
  }, {
    "Y": 2016,
    "M": 23424
  }, {
    "Y": 2017,
    "M": 23297
  }, {
    "Y": 2018,
    "M": 24412.5
  }, {
    "Y": 2019,
    "M": 27090.5
  }, {
    "Y": 2020,
    "M": 29754.5
  }]
 }]
});

HTML

<table border="1" data-ng-app="testModule" data-ng-controller="testController">
   <thead>
    <tr>
      <th ng-repeat="i in headerYears">{{i}}</th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="row in rows">
      <td ng-repeat="item in row.Col">{{item.M}}{{item.Y}}</td>
    </tr>
  </tbody>

如果在DOM 中,我会做一个ng

<table border="1" data-ng-app="testModule" data-ng-controller="testController">
  <thead>
    <tr>
      <th ng-repeat="i in headerYears">{{i}}</th>
    </tr>
  </thead>
  <tbody>
    <tr >
      <td ng-repeat="i in headerYears" >{{i}}  
      <span ng-repeat="row in rows"></span> 
      <span ng-repeat="item in row.Col">{{item.Y}} </span>
      </td>     
    </tr>
  </tbody>
</table>

编辑:您可以将一个NG-IF添加到span NG-IF="item.Y=i"和另一个span NG-IF-"itemY.!=i"

由于row.col的长度可以小于、大于或等于headerYears长度,因此您必须确保表在列上具有一致性。

这意味着对于每一行,您必须在headerYears上收割才能创建相同的列大小。

看看我创建的plunker,它可能会给你解决方案。

此外,创建一个新的对象数组也是一个好主意,该数组与控制器中提供的年份绑定,然后对这个新数组重复。

Imho这将提供更干净的DOM,并且可以更容易地维护。

我添加了一个过滤器,以便读取列数据并返回适合每种情况的数据。

 app.filter('testFilter', function() {
    return function(col, header) {
       if (!col ){
        return "Empty";
       } 
       if (!header){
        return "Empty"; 
       }

       var returnVal="Empty Item";
       angular.forEach(col, function(colItem){
         if(header===colItem.Y) {
            returnVal = colItem.M+" "+colItem.Y;
        }
       });
    return returnVal;
   }
});

我还更改了DOM,现在它看起来有点像下面的

<tbody>
   <tr ng-repeat="row in rows">
      <td ng-repeat="i in headerYears">
         {{row.Col | testFilter:i }}
      </td>
   </tr>
</tbody>

这样做效果很好,比为您想要显示的每个值构建自定义过滤器要好(即,您可以将任何想要的HTML放入TD中,只需像正常情况一样使用{{item.myProperty}}})。享受

它将所有数据放入与标头匹配的格式中,让JS做它最擅长的事情,然后将干净的数据提供给Angular。希望能有所帮助!

//START OF GOOD CODE
$scope.rows = null;
(function(){
  var raw = [{ /** this is all your current "rows" data, just moved**/ }];
  var bucketize = function(col) {
      var data = new Array();
      for (var i = 0; i < $scope.headerYears.length; i++) {
          data.push({}); //initialize to match headerYears setup
          for (var j = 0; j < col.length; j++) {
              if (col[j].Y == $scope.headerYears[i]) {
                  data[i] = col[j]; //replace initialized value with real data
              }
          }
      }
      return data;
  };
  var rows = new Array();
  for (var x = 0; x < raw.length; x++) {
    var row = raw[x];
    row.Col = bucketize(row.Col); //sort data and format it for our desired HTML        
    rows.push(row);
  }
  $scope.rows = rows; //give the scrubbed data to Angular
})();
//END OF GOOD CODE

--编辑--

下面创建了一个无限摘要循环,因为它在每次调用buketize()函数时都会返回一个新的Array()。相反,在将数据提供给Angular之前先清除数据(请参见上文)。您可以在AJAX成功处理程序中做到这一点,甚至可以像我上面所做的那样使用SEAF。

//NOTE THIS IS BAD, DUE TO INFINITE LOOP CAUSED BY "new Array();"
...
<td ng-repeat="item in bucketize(row.Col)">{{item.Y}}</td>
...
$scope.bucketize = function(col) {
    var data = new Array();
    for (var i = 0; i < $scope.headerYears.length; i++) {
        data.push({}); //initialize to match headerYears setup
        for (var j = 0; j < col.length; j++) {
            if (col[j].Y == $scope.headerYears[i]) {
                data[i] = col[j]; //replace initialized value with real data
            }
        }
    }
    return data;
};
//END OF BAD CODE
  • Kieron