使用* ngFor生成两个表行

时间:2018-08-19 03:32:39

标签: html angular html-table

我正在开发一个应用程序,以显示使用Java的TestNG测试网站的结果。我知道这有点多余,因为TestNG已经生成了自己的网站,但这是训练营培训的一部分。

在使用*ngFor生成表时遇到了一个特殊的问题。问题是,如果测试返回失败,它将返回堆栈跟踪。因为Java堆栈跟踪非常冗长,所以该堆栈跟踪位于新行上,因此我无法像通常那样将*ngFor放在<tr>标记上。我不愿意将其放在<tbody>标记上,因为我担心这会导致布局问题(确实如此),所以我尝试将两个<tr>标记包装在<div>中,然后将*ngFor。那是行不通的,因为现在我的表标题与表的内容不对齐。我最终将*ngFor指令放在<tbody>上,这似乎 几乎没事,即使它在我的行之间产生了一些带有边界的伪像。

但是我仍然不喜欢这种方法。它不仅很老套,而且在非常大的布局上也会产生一些错误。

<table class="table table-striped table-dark table-hover table-sm table-responsive" *ngIf="loaded">
<thead>
    <tr>
        <th>Name</th>
        <th>Signature</th>
        <th>Duration</th>
        <th>Started At</th>
        <th>Finished At</th>
        <th>Status</th>
    </tr>
</thead>
<tbody *ngFor="let method of testResults.tests; let index = index">
        <tr>
            <td>{{ method.name | camelToTitle }}</td>
            <td>{{ method.signature }}</td>
            <td>{{ method.duration_ms }} ms</td>
            <td>{{ method.startTime | dates }}</td>
            <td>{{ method.finishTime | dates }}</td>
            <td
                [ngStyle]="{ background: selectColor(method.status) }">
                {{ method.status |passfail }}
            </td>
        </tr>
        <tr>
            <td *ngIf="method.exceptionClass != null" class="table-danger">{{ method.exceptionClass }}</td>
            <td *ngIf="method.exceptionClass != null" colspan="5" class="table-danger">
                <button class="btn btn-dark" (click)="toggleStackTrace(index)">{{ btnText }} Stack Trace</button>
                <span class="font-weight-bold ml-1">Exception Message: {{ method.exceptionMessage }}</span>
                <div *ngIf="method.showStackTrace">
                    <p [appStacktrace]="method.stackTrace"></p>
                </div>
            </td>
        </tr>
</tbody>
</table>

基本上,我想做的是为要运行的每个测试生成一行,并且,如果该测试具有堆栈跟踪,那么也要为此生成一行。有没有一种好的,干净的方法可以做到这一点?

1 个答案:

答案 0 :(得分:1)

执行此操作的最佳方法是使用ng-container

Angular文档将ng-container描述为

  

由于Angular不会将其放置在DOM中而不会干扰样式或布局的分组元素。

read more here

这使您可以将HTML包装在ng-container标记中,如下所示:

<table class="table table-striped table-dark table-hover table-sm table-responsive" *ngIf="loaded">
<thead>
    <tr>
        <th>Name</th>
        <th>Signature</th>
        <th>Duration</th>
        <th>Started At</th>
        <th>Finished At</th>
        <th>Status</th>
    </tr>
</thead>
<tbody>
    <ng-container *ngFor="let method of testResults.tests; let index = index">
        <tr>
            <td>{{ method.name | camelToTitle }}</td>
            <td>{{ method.signature }}</td>
            <td>{{ method.duration_ms }} ms</td>
            <td>{{ method.startTime | dates }}</td>
            <td>{{ method.finishTime | dates }}</td>
            <td
                [ngStyle]="{ background: selectColor(method.status) }">
                {{ method.status |passfail }}
            </td>
        </tr>
        <tr>
            <td *ngIf="method.exceptionClass != null" class="table-danger">{{ method.exceptionClass }}</td>
            <td *ngIf="method.exceptionClass != null" colspan="5" class="table-danger">
                <button class="btn btn-dark" (click)="toggleStackTrace(index)">{{ btnText }} Stack Trace</button>
                <span class="font-weight-bold ml-1">Exception Message: {{ method.exceptionMessage }}</span>
                <div *ngIf="method.showStackTrace">
                    <p [appStacktrace]="method.stackTrace"></p>
                </div>
            </td>
        </tr>
    </ng-container>
</tbody>
</table>

*ngFor的行为得以保留,但是DOM将仅包含预期的标签({tbodytrtd等)