使用 *ngFor 生成两行表格 [英] Generating Two Table Rows With *ngFor
问题描述
我正在开发一个应用程序来显示使用 Java 的 TestNG 测试网站的结果.我知道这有点多余,因为 TestNG 已经生成了自己的网站,但它是训练营训练练习的一部分.
我在用 *ngFor
生成表格时遇到了一个奇怪的问题.问题是,如果测试返回失败,它会返回堆栈跟踪.由于 Java 堆栈跟踪非常冗长,堆栈跟踪被放置在新行上,因此我不能像通常那样将 *ngFor
放在 <tr>
标记上做.我犹豫是否将它放在 <tbody>
标签上,因为我担心这会导致布局问题(确实如此),所以我尝试将两个 <tr>
包装起来> 标记在
*ngFor
放在上面.那没有用,因为现在我的表格标题没有与表格的内容对齐.我最终将 *ngFor
指令放在 <tbody>
上,因为这看起来大部分没问题,尽管它在我的行就像有边框一样.但是我仍然不喜欢这种方法.它不仅很笨拙,而且会在非常大的布局上产生一些错误.
<头><tr><th>姓名</th><th>签名</th><th>持续时间</th><th>开始于</th><th>完成于</th><th>状态</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 |日期}}</td><td>{{ method.finishTime |日期}}</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">异常消息:{{ method.exceptionMessage }}</span><div *ngIf="method.showStackTrace"><p [appStacktrace]="method.stackTrace"></p></td></tr></tbody>
基本上我要做的是为每个运行的测试生成一行,如果测试有堆栈跟踪,也有一行.有没有一种好的、干净的方法来做这件事?
最好的方法是使用 ng-container
.
Angular 文档将 ng-container 描述为
<块引用>不会干扰样式或布局的分组元素,因为 Angular 不会将其放入 DOM 中.
这允许您将 HTML 包装在 ng-container
标签中,如下所示:
<头><tr><th>姓名</th><th>签名</th><th>持续时间</th><th>开始于</th><th>完成于</th><th>状态</th></tr></thead><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 |日期}}</td><td>{{ method.finishTime |日期}}</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">异常消息:{{ method.exceptionMessage }}</span><div *ngIf="method.showStackTrace"><p [appStacktrace]="method.stackTrace"></p></td></tr></ng-容器></tbody>
*ngFor
的行为得到维护,但 DOM 将只包含预期的标签(tbody
、tr
、td
等)
I am working on an application to display the results of testing a website with Java's TestNG. I know it's a bit redundant since TestNG already generates its own site, but it's part of a training exercise for a bootcamp.
I've come upon a peculiar issue while generating a table with *ngFor
. The issue is that if a test comes back failed, it comes back with a stack trace. Because Java stack traces are so verbose, that stack trace is placed on a new row, therefore I cannot put the *ngFor
on the <tr>
tag as one would normally do. I was hesitant to put it on the <tbody>
tag because I feared that that would cause layout issues (and it does) so I tried wrapping the two <tr>
tags in a <div>
and putting the *ngFor
on that. That did not work, because now my table headers weren't aligned with the table's content. I ended up putting the *ngFor
directive on the <tbody>
as that seemed mostly all right, even though it produced some artifacts between my rows as if they have borders.
However I still don't like that approach. Not only is it hacky as it is, it creates some bugs on very large layouts.
<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>
Essentially what I'm trying to do is generate a row for each test that gets run, and, if the test has a stacktrace, have a row for that as well. Is there a good, clean way to go about doing this?
The best way to do this would be to use ng-container
.
The Angular docs describe ng-container as
a grouping element that doesn't interfere with styles or layout because Angular doesn't put it in the DOM.
This allows you to wrap your HTML in an ng-container
tag, like so:
<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>
The behavior of *ngFor
is maintained, but the DOM will only ever contain the expected tags (tbody
, tr
, td
, etc)
这篇关于使用 *ngFor 生成两行表格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!