使用ng-repeat填充表并检查匹配的标题数据

时间:2016-04-12 15:51:39

标签: javascript angularjs

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

CONTROLLER

 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>

3 个答案:

答案 0 :(得分:0)

我会在DOM中进行ng-if

Category.with_max_version_number

编辑:您可以在跨度中添加NG-IF,例如span ng-if =“item.Y == i”和另一个跨度ng-if =“item.Y!= i”

答案 1 :(得分:0)

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

这意味着对于每一行,您必须在headerYears上重新创建以创建相同的列大小。

看看我创建的plunker,它可以为您提供解决方案。

同样最好创建一个新的对象数组,这些对象绑定到控制器中提供的年份,然后对这个新数组进行ng-repeat。

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>

答案 2 :(得分:0)

这很好,并且比为您想要显示的每个值构建自定义过滤器更好(例如,您可以在TD中放置任何您喜欢的HTML,并且像正常情况一样使用{{item.myProperty}}。享受!

它将您的所有数据放入与标题匹配的格式中,这样JS就可以执行最佳操作,然后向Angular提供干净的数据。希望有所帮助!

.select()

- 编辑 -

以下内容创建了一个无限的摘要循环,因为它在每次调用bucketize()函数时返回一个新的Array()。相反,在将数据提供给Angular之前擦除数据(参见上文)。您可以在AJAX成功处理程序中完成此操作,甚至可以像上面那样使用SEAF。

//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
  • 基隆