使用多级分组在 HTML 表格中显示数据

Posted

技术标签:

【中文标题】使用多级分组在 HTML 表格中显示数据【英文标题】:Display data in HTML table with multi level grouping 【发布时间】:2019-12-03 16:57:16 【问题描述】:

我必须通过使用 rowspan 进行分组来显示 html 表中的一些数据。 以下是预期的 GUI

我有如下 JSON 数据。 JSON数据here

角度代码

<table class="table table-fixed" border="1">
            <thead>
               <tr>
        <th>Country</th>
        <th>State</th>
        <th>City</th>
        <th>Street</th>
        <th>Male</th>
        <th>Female</th>
        <th>Others</th>
    </tr>
            </thead>
            <tbody>
                <ng-container *ngFor="let country of Countries">
                    <tr *ngFor="let item of [].constructor(country.NoOfStreets); let streetIdx = index">
                        <ng-container *ngFor="let state of country.States; let stateIdx = index">

                            <td [attr.rowspan]="state.NoOfStreets" style="width: 15%">
                                state.StateName  
                            </td>

                        </ng-container>

                         <ng-container *ngFor="let state of country.States; let stateIdx = index">
                            <ng-container *ngFor="let city of state.Cities; let cityIdx = index">
                                <td [attr.rowspan]="city.NoOfStreets" style="width: 15%">city.CityName</td>

                                <ng-container *ngFor="let street of city.Streets; let streetIdx = index">
                                <td style="width: 15%">street.StreetName</td>
                                <td style="width: 15%">street.Male</td>
                                 <td style="width: 15%">street.Female</td>
                                  <td style="width: 15%">street.Others</td>
                            </ng-container>

                            </ng-container>
                        </ng-container>
                    </tr>
                </ng-container>
            </tbody>

        </table>

我无法生成预期的 UI。我得到了不同的用户界面并且没有正确呈现。我尝试了这个几乎一个星期,但没有任何结果。

PLUNK 版本是https://next.plnkr.co/edit/5nYNZ86BiWDke3GE?open=lib%2Fapp.ts&deferRun=1

【问题讨论】:

从 REST 调用接收的数据是否可能?我似乎只能找到人们发布关于使用静态数据执行此操作的信息,所以我很困惑这是否不可能,或者人们只是不知道该怎么做? 【参考方案1】:

您想要的是将所有 streats 展平为数组,以便您对其进行循环。平面代码将是:

      const concat = (x,y) => x.concat(y)
      const flatMap = (f,xs) => xs.map(f).reduce(concat, [])


        let states = flatMap(c => c.States.map(s => (Country:c, State: s)), this.Countries);
        let cities = flatMap(c => c.State.Cities.map(s => (Country:c.Country, State:c.State, City: s)), states);

        this.streets = flatMap(c => c.City.Streets.map(str => (Country:c.Country,     State:c.State, City: c.City, Street: str)), cities);

然后轻松检查每个国家、州和城市是否在组中的第一个,例如:

  <tbody>               
                <tr *ngFor="let str in streets">
                    <td *ngIf="firstCountryInGroup(str)" [rowspan]="numberOfCountry(str)">
                        str.Country.CountryName
                    </td>
                    <td *ngIf="firstStateInGroup(str)" [rowspan]="numberOfStatse(str)">
                        str.State.CityName
                    </td>
                    <td *ngIf="firstCityInGroup(str)" [rowspan]="numberOfCities(str)">
                        str.City.CityName
                    </td>
                    <td>str.Street.Name<td>
                    <td>str.Street.Male<td>
                    <td>str.Street.Female<td>
                    <td>str.StreetOthers<td>
                </tr>               
            </tbody>

【讨论】:

你有 plnkr 或 stackblitz 吗?我正在尝试使用现有的 plnkr 进行更新,看起来我需要为地图导入一些 RxJs? next.plnkr.co/edit/… 这是有趣的小代码 看起来不错。如果可行,我会尝试并接受您的回答:)太好了 我接受了。谢谢!。我正在尝试在国家/地区之前添加一个像区域这样的分组。就像let countris = flatMap(c =&gt; c.Countries.map(s =&gt; (Country:s, Region: c)), this.Regions); let states = flatMap(c =&gt; c.States.map(s =&gt; (Country:c, State: s)), countris); 不知道这如何与flatMap 完全一致。您能否提供一个提示或一些适用于更高级别分组的代码?到目前为止,它还不能再使用一个级别【参考方案2】:

我们需要有单独的列,我们在其中运行基于子级或兄弟级的循环 - 您还将从下面代码中的 cmets 中得到这个想法

相关TS

<table class="table table-fixed" border="1">
    <thead>
        <tr>
            <th>Country</th>
            <th>State</th>
            <th>City</th>
            <th>Street</th>
            <th>Male</th>
            <th>Female</th>
            <th>Others</th>
        </tr>
    </thead>
    <tbody>
        <ng-container *ngFor="let country of Countries; let i = index">
            <tr>
                <!-- column 1 -->
                <td>country.CountryName</td>
                <!-- column 2 -->
                <td>
                    <ng-container *ngFor="let state of country.States">
                        <tr>
                            <td> state.StateName </td>
                        </tr>
                    </ng-container>
                </td>
                <!-- column 3 -->
                <td>
                    <ng-container *ngFor="let state of country.States">
                        <tr>
                            <td>
                                <ng-container *ngFor="let city of state.Cities">
                                    <tr>
                                        <td> city.CityName </td>
                                    </tr>
                                </ng-container>

                            </td>
                        </tr>
                    </ng-container>
                </td>

                <!-- column 4 -->
                <td>
                    <ng-container *ngFor="let state of country.States">
                        <tr>
                            <td>
                                <ng-container *ngFor="let city of state.Cities">
                                    <tr>
                                        <td>
                                            <ng-container *ngFor="let street of city.Streets">
                                                <tr>
                                                    <td>
                                                        street.StreetName

                                                    </td>
                                                </tr>
                                            </ng-container>

                                        </td>
                                    </tr>
                                </ng-container>

                            </td>
                        </tr>
                    </ng-container>
                </td>

                <!-- column 5 -->
                <td>
                    <ng-container *ngFor="let state of country.States">
                        <tr>
                            <td>
                                <ng-container *ngFor="let city of state.Cities">
                                    <tr>
                                        <td>
                                            <ng-container *ngFor="let street of city.Streets">
                                                <tr>
                                                    <td>
                                                        street.Male

                                                    </td>
                                                </tr>
                                            </ng-container>

                                        </td>
                                    </tr>
                                </ng-container>

                            </td>
                        </tr>
                    </ng-container>
                </td>

                <!-- column 6 -->
                <td>
                    <ng-container *ngFor="let state of country.States">
                        <tr>
                            <td>
                                <ng-container *ngFor="let city of state.Cities">
                                    <tr>
                                        <td>
                                            <ng-container *ngFor="let street of city.Streets">
                                                <tr>
                                                    <td>
                                                        street.Female

                                                    </td>
                                                </tr>
                                            </ng-container>

                                        </td>
                                    </tr>
                                </ng-container>

                            </td>
                        </tr>
                    </ng-container>
                </td>

                <!-- column 7 -->
                <td>
                    <ng-container *ngFor="let state of country.States">
                        <tr>
                            <td>
                                <ng-container *ngFor="let city of state.Cities">
                                    <tr>
                                        <td>
                                            <ng-container *ngFor="let street of city.Streets">
                                                <tr>
                                                    <td>
                                                        street.Others

                                                    </td>
                                                </tr>
                                            </ng-container>

                                        </td>
                                    </tr>
                                </ng-container>

                            </td>
                        </tr>
                    </ng-container>
                </td>


            </tr>

        </ng-container>
    </tbody>

</table>

工作stackblitz here

【讨论】:

它不提供干净的分组。在您的示例中,城市被合并,用户无法按城市查看清晰的信息【参考方案3】:

有了这个解决方案

https://stackblitz.com/edit/angular-gbhcun?file=src/app/app.component.html

添加以下样式以满足精确输出

table, th, td 
  border: 1px solid black;

【讨论】:

以上是关于使用多级分组在 HTML 表格中显示数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在网格/表格中显示分组/分类缩略图,如布局

在 Swift 中使用 Core Data 在表格视图的部分中显示数据

如何使用电子表格中的两个不同列制作按图分组的条形图?

如何让我的表格正确显示分组数据?

Eement UI 中 Table 表格 多级合并单元格方式

Eement UI 中 Table 表格 多级合并单元格方式