从模型 AngularJS 创建 table

Create table from model AngularJS

我需要一些帮助来使用 Angular 模型渲染 html table。

首先,我有一个模型指定我需要渲染一个 table,以及一个需要在 table 中显示的 "questions" 的列表。

数据示例:

   {

    "Id": 25546,
    "questionType": "Table",
    "maxRows": 2,
    "maxCols": 3,
    "questionsInTable": [{
        "isActive": true,
        "questionText": "Table Title",
        "validation": "false",
        "rowPosition": 1,
        "colPosition": 1,
        "isPrintable": true,
        "Answer": null,
        "Type": "Label"
    }, {
        "isActive": true,
        "questionText": "2014",
        "validation": "false",
        "rowPosition": 1,
        "colPosition": 2,
        "isPrintable": true,
        "Answer": null,
        "Type": "Label"
    }, {
        "isActive": true,
        "questionText": "2013",
        "validation": "false",
        "rowPosition": 1,
        "colPosition": 3,
        "isPrintable": true,
        "Answer": null,
        "Type": "Label"
    }, {
        "isActive": true,
        "questionText": "Another description here",
        "validation": "false",
        "rowPosition": 2,
        "colPosition": 1,
        "isPrintable": true,
        "Answer": null,
        "Type": "Label"
    }, {
        "isActive": true,
        "questionText": "DescFor2014",
        "validation": "true",
        "rowPosition": 2,
        "colPosition": 2,
        "isPrintable": true,
        "Answer": null,
        "Type": "InputText"
    }, {
        "isActive": true,
        "questionText": "DescFor2013",
        "parentQuestion": 25546,
        "validation": "true",
        "rowPosition": 2,
        "colPosition": 3,
        "isPrintable": true,
        "Answer": null,
        "Type": "InputText"
    }]
}

每个项目(或问题)都提供 table 中的行和列位置,而且数据有两个项目的行和列的最大值。我可以使用 MaxRows 和 MaxCols 数据创建 table,但我很难将问题插入正确的单元格。

结果应该是上面的例子:

渲染输出示例:

<table>
<tr>
    <td>Table Title</td>
    <td>2014</td>
    <td>2013</td>
</tr>
    <tr>
        <td>Another description here</td>
        <td>DescFor2014</td>
        <td>DescFor2013</td>
    </tr>
</table>

有没有办法做到这一点?

非常感谢你的帮助,或者如果你能指出正确的方向。

请参考这个插件:http://plnkr.co/edit/xTagjy1n9tl0CvnDH5Q3?p=preview

你基本上必须 ng-repeat 行直到 maxRows 和 ng-repeat cols 直到 maxCols:

<table>
  <tr ng-repeat="i in [] | range:(tableData.maxRows)">
    <td ng-repeat="j in [] | range:(tableData.maxCols)">
      {{tableData.questionsInTable[j + i*tableData.maxCols].questionText}}
    </td>
  </tr>
</table>

范围是一个过滤函数:

 angular.module('app').filter('range', function() {
  return function(input, total) {
    total = parseInt(total);
    for (var i=0; i<total; i++)
      input.push(i);
    return input;
  };
});

注意:这仅在以下情况下有效:

  1. 行、列对已排序。如果不是,你将不得不对它们进行排序 首先,然后将其绑定到 table

  2. 不适用于稀疏数组。在稀疏数组的情况下,您将不得不创建虚拟对象,在创建时应忽略这些虚拟对象 table

在继续之前,还要验证您发布的问题中的 JSON 对象。它看起来不正确: http://jsonlint.com/

我已经为您的解决方案创建了一个 Plunkr - http://plnkr.co/edit/4vUm8yRiDKlTM8lnQH7E?p=preview.

要为 table 创建 row/column,我创建了 2 个数组 - 行和列。

      $scope.rows = [];
          for (var i=0;i<$scope.tableData.maxRows;i++) {
          $scope.rows.push(i);
      }

      $scope.cols = [];
          for (var i=0;i<$scope.tableData.maxCols;i++) {
          $scope.cols.push(i);
      }

HTML 已保存为:

<table>
  <tr ng-repeat="i in rows">
    <td ng-repeat="j in cols">
      <div table-pos object="tableData.questionsInTable" row="i" col="j"></div>
    </td>
  </tr>
</table>

table-pos 是一个指令,它将接受问题数组、行和列索引作为范围属性。我使用 underscore.js 从问题集合中提取正确的对象并显示该位置的问题(基于 rowPosition 和 colPosition)。代码如下所示:

.directive("tablePos", function() {
  return {
  template: "<div>{{data}}</div>",
  scope: {
    object: "=",
    row: "=",
    col:"="
  },
  link: function(scope) {
    var questions = scope.object; 
    var question= _.findWhere(questions, {colPosition:scope.col+1, rowPosition: scope.row+1});
    scope.data = question.questionText;
  }
  }
})

使用指令的主要优点是列表中的问题不需要按任何顺序排序。所以你可以在你的数组中以任何顺序添加问题。只要正确定义了 rowPosition 和 colPosition,指令就会选择它。
此外,该指令还支持 空 cells/sparse 数组 ,因此如果不存在针对特定单元格的任何问题,该指令将显示空数据。

一个缺点是,如果超过 1 个问题具有相同的 rowPosition 和 colPosition,那么只会选择第一个问题,而其余的问题将被默默地忽略。

请注意,如果您不想使用 underscope.js,您仍然可以使用普通的 JavaScript 从列表中检测正确的问题。但是,使用 underscore.js 会更容易,因为底层逻辑是抽象的。