使用 *ngFor 生成两行表格 [英] Generating Two Table Rows With *ngFor

查看:33
本文介绍了使用 *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 将只包含预期的标签(tbodytrtd 等)

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.

read more here

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆