简体   繁体   English

AngularJS:如何构建具有多层深度数据的HTML表?

[英]AngularJS: how to build an HTML table with data multiple-levels deep?

I need to create a table from some data with multiple levels of arrays and sub-arrays. 我需要从一些具有多级数组和子数组的数据创建一个表。 I have found some solutions to do this as long as I only have two levels of arrays, but none that would work with anything more than that. 我已经找到了一些解决方案,只要我只有两个级别的数组,但没有一个可以用于更多的数组。

For example, take the sample data below -- 例如,下面的示例数据 -

$scope.professors = [{
    'name': 'Albert Einstein',
    'classes': [{
        'name': 'Physics 101',
        'students': [{
            'name': 'Joe',
            'grade': 'B'
        }, {
            'name': 'Mary',
            'grade': 'A'
        }]
    }, {
        'name': 'Physics 201',
        'students': [{
            'name': 'Gunther',
            'grade': 'C'
        }, {
            'name': 'Hans',
            'grade': 'C'
        }]
    }]
}, {
    'name': 'Charles Darwin',
    'classes': [{
        'name': 'Biololgy 101',
        'students': [{
            'name': 'Danielle',
            'grade': 'A'
        }, {
            'name': 'Anne',
            'grade': 'A'
        }]
    }, {
        'name': 'Biology 201',
        'students': [{
            'name': 'Frida',
            'grade': 'A'
        }, {
            'name': 'Fritz',
            'grade': 'F'
        }]
    }]
}];

You have some professors each with some disciplines each in turn with some students enrolled. 你有一些教授,每个教授都有一些学科,每个学科都有一些学生注册。 I want to create a table-report that show all professors along with all their disciplines and students and grades. 我想创建一个表格报告,显示所有教授以及他们的所有学科,学生和成绩。 In order to do this, I would need a table such as the one below -- 为了做到这一点,我需要一个如下表所示的表 -

<table>
    <tbody>
        <tr>
            <th rowspan="4">Albert Einstein</th>
            <th rowspan="2">Physics 101</th>
            <td>Joe</td>
            <td>B</td>
        </tr>
        <tr>
            <td>Mary</td>
            <td>A</td>
        </tr>
        <tr>
            <th rowspan="2">Physics 201</th>
            <td>Gunther</td>
            <td>C</td>
        </tr>
        <tr>
            <td>Hans</td>
            <td>C</td>
        </tr>
        <tr>
            <th rowspan="4">Charles Darwin</th>
            <th rowspan="2">Biology 101</th>
            <td>Danielle</td>
            <td>A</td>
        </tr>
        <tr>
            <td>Anne</td>
            <td>A</td>
        </tr>
        <tr>
            <th rowspan="2">Biology 201</th>
            <td>Frida</td>
            <td>A</td>
        </tr>
        <tr>
            <td>Fritz</td>
            <td>F</td>
        </tr>
    </tbody>
</table>

ie

|------------------|-------------|----------|---|
| Albert Einstein  | Physics 101 | Joe      | B |
|                  |             | Mary     | A |
|                  | ------------|----------|---|
|                  | Physics 201 | Gunther  | C |
|                  |             | Hans     | C |
|------------------|-------------|----------|---|
| Charles Darwin   | Biology 101 | Danielle | A |
|                  |             | Anne     | A |
|                  |-------------|----------|---|
|                  | Biology 201 | Frida    | A |
|                  |             | Fritz    | F |
|------------------|-------------|----------|---|

The solutions I've found generate multiple tbody elements with ng-repeat for each professor (in this case) and then another ng-repeat on a tr for each "class" for that professor. 我已经找到了解决方案生成多个tbody的元素ng-repeat每个教授(在这种情况下),然后又ng-repeat上一个tr每个“类”为教授。 Like -- 喜欢 -

<table>
    <tbody ng-repeat="prof in professors">
        <tr ng-repeat="c in prof.classes">
            <th ng-if="$first" rowspan="{{prof.classes.length}}">{{prof.name}}</th>
            <td>{{c.name}}</td>
        </tr>
    </tbody>
</table>

Others use ng-repeat-start and ng-repeat-end but none more than two levels deep. 其他人使用ng-repeat-startng-repeat-end但不超过两个级别。 Is there a way to add one more level—in this case, the students—to this? 有没有办法再增加一个级别 - 在这种情况下,学生 - 这个?

After much frustration and head scratching, I found a way to do it using ng-repeat-start 经过很多挫折和头疼,我找到了一种方法,使用ng-repeat-start

<table>
    <tbody>
        <tr ng-repeat-start="p in professors" ng-if="false"></tr>
        <tr ng-repeat-start="c in p.classes" ng-if="false"></tr>
        <tr ng-repeat="s in c.students">
            <th ng-if="$parent.$first && $first" rowspan="{{p.count}}">
                {{p.name}}
            </th>
            <th ng-if="$first" rowspan="{{c.students.length}}">{{c.name}}</th>
            <td>{{s.name}}</td>
            <td>{{s.grade}}</td>
        </tr>
        <tr ng-repeat-end ng-if="false"></tr> <!-- classes -->
        <tr ng-repeat-end ng-if="false"></tr> <!-- professors -->
    </tbody>
</table>

This solution generates valid HTML table markup. 此解决方案生成有效的HTML表标记。 By using ng-if="false" on the ng-repeat-* elements, they iterate through the arrays but generate no actual element on the page. 通过在ng-repeat-*元素上使用ng-if="false" ,它们遍历数组但在页面上不生成实际元素。 The only elements generated are the tr rows in s in c.students . 生成的唯一元素是s in c.studentss in c.studentstr行。

The other thing I needed to do is create a new property inside the professor objects named count that holds the total number of students enrolled in all the classes. 我需要做的另一件事是在名为countprofessor对象中创建一个新属性,该对象包含在所有类中注册的学生总数。 I needed that for the rowspan and it's of course trivial to generate on the fly when I get data from the server. 对于rowspan我需要它,当我从服务器获取数据时,它当然很容易生成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM