• Table表格
    • 何时使用
    • 如何使用
      • 高度定制
      • 组件增强
      • 数据处理
    • 代码演示
    • API
      • 单独引入此组件
      • nz-tablecomponent
      • th
      • td
      • thead
      • tr
      • [nz-virtual-scroll]directive
    • 注意

    Table表格

    展示行列数据。

    何时使用

    • 当有大量结构化的数据需要展现时;
    • 当需要对数据进行排序、搜索、分页、自定义操作等复杂行为时。

    如何使用

    Table 组件同时具备了易用性和高度可定制性

    高度定制

    nz-table 组件中完整的暴露了 W3C标准 <table> 的所有组成部分,你可以像使用 table 元素一样使用 nz-table ,根据依据业务需求,使用者可以自由的控制任何一个部分的样式、内容、逻辑和事件绑定。

    组件增强

    nz-table, thead, th, td 等多个暴露的元素上,组件提供了增强语法,经过配置之后可以很方便的实现多选、过滤、排序、固定列、固定表头、服务端分页等功能。

    数据处理

    传入[nzData]中的数据,经过处理之后,可以通过 模板变量 获取当前展示表格部分的数据,再使用 *ngFor 依据需求将数据渲染。

    1. <nz-table #basicTable [nzData]="dataSet">
    2. <thead>
    3. <tr>
    4. <th>Name</th>
    5. <th>Age</th>
    6. <th>Address</th>
    7. <th>Action</th>
    8. </tr>
    9. </thead>
    10. <tbody>
    11. <tr *ngFor="let data of basicTable.data">
    12. <td>{{data.name}}</td>
    13. <td>{{data.age}}</td>
    14. <td>{{data.address}}</td>
    15. <td>
    16. <a>Action 一 {{data.name}}</a>
    17. <nz-divider nzType="vertical"></nz-divider>
    18. <a>Delete</a>
    19. </td>
    20. </tr>
    21. </tbody>
    22. </nz-table>

    代码演示

    Table表格 - 图1

    基本用法

    简单的表格,最后一列是各种操作。

    1. import { Component } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-table-basic',
    4. template: `
    5. <nz-table #basicTable [nzData]="listOfData">
    6. <thead>
    7. <tr>
    8. <th>Name</th>
    9. <th>Age</th>
    10. <th>Address</th>
    11. <th>Action</th>
    12. </tr>
    13. </thead>
    14. <tbody>
    15. <tr *ngFor="let data of basicTable.data">
    16. <td>{{ data.name }}</td>
    17. <td>{{ data.age }}</td>
    18. <td>{{ data.address }}</td>
    19. <td>
    20. <a>Action 一 {{ data.name }}</a>
    21. <nz-divider nzType="vertical"></nz-divider>
    22. <a>Delete</a>
    23. </td>
    24. </tr>
    25. </tbody>
    26. </nz-table>
    27. `
    28. })
    29. export class NzDemoTableBasicComponent {
    30. listOfData = [
    31. {
    32. key: '1',
    33. name: 'John Brown',
    34. age: 32,
    35. address: 'New York No. 1 Lake Park'
    36. },
    37. {
    38. key: '2',
    39. name: 'Jim Green',
    40. age: 42,
    41. address: 'London No. 1 Lake Park'
    42. },
    43. {
    44. key: '3',
    45. name: 'Joe Black',
    46. age: 32,
    47. address: 'Sidney No. 1 Lake Park'
    48. }
    49. ];
    50. }

    Table表格 - 图2

    选择和操作

    第一列是联动的选择框,增加 nzShowCheckbox 后,th 获得和 nz-checkbox 一样的功能,选择后进行操作,完成后清空选择,请注意:数据逻辑需要自行控制。

    1. import { Component, OnInit } from '@angular/core';
    2. export interface Data {
    3. id: number;
    4. name: string;
    5. age: number;
    6. address: string;
    7. disabled: boolean;
    8. }
    9. @Component({
    10. selector: 'nz-demo-table-row-selection-and-operation',
    11. template: `
    12. <div class="operate">
    13. <button
    14. nz-button
    15. [disabled]="numberOfChecked === 0"
    16. [nzType]="'primary'"
    17. [nzLoading]="isOperating"
    18. (click)="operateData()"
    19. >
    20. Reload
    21. </button>
    22. <span *ngIf="numberOfChecked">Selected {{ numberOfChecked }} items</span>
    23. </div>
    24. <nz-table
    25. #rowSelectionTable
    26. nzShowPagination
    27. nzShowSizeChanger
    28. [nzData]="listOfAllData"
    29. (nzCurrentPageDataChange)="currentPageDataChange($event)"
    30. >
    31. <thead>
    32. <tr>
    33. <th
    34. nzShowCheckbox
    35. [(nzChecked)]="isAllDisplayDataChecked"
    36. [nzIndeterminate]="isIndeterminate"
    37. (nzCheckedChange)="checkAll($event)"
    38. ></th>
    39. <th>Name</th>
    40. <th>Age</th>
    41. <th>Address</th>
    42. </tr>
    43. </thead>
    44. <tbody>
    45. <tr *ngFor="let data of rowSelectionTable.data">
    46. <td
    47. nzShowCheckbox
    48. [(nzChecked)]="mapOfCheckedId[data.id]"
    49. [nzDisabled]="data.disabled"
    50. (nzCheckedChange)="refreshStatus()"
    51. ></td>
    52. <td>{{ data.name }}</td>
    53. <td>{{ data.age }}</td>
    54. <td>{{ data.address }}</td>
    55. </tr>
    56. </tbody>
    57. </nz-table>
    58. `,
    59. styles: [
    60. `
    61. .operate {
    62. margin-bottom: 16px;
    63. }
    64. .operate span {
    65. margin-left: 8px;
    66. }
    67. `
    68. ]
    69. })
    70. export class NzDemoTableRowSelectionAndOperationComponent implements OnInit {
    71. isAllDisplayDataChecked = false;
    72. isOperating = false;
    73. isIndeterminate = false;
    74. listOfDisplayData: Data[] = [];
    75. listOfAllData: Data[] = [];
    76. mapOfCheckedId: { [key: string]: boolean } = {};
    77. numberOfChecked = 0;
    78. currentPageDataChange($event: Data[]): void {
    79. this.listOfDisplayData = $event;
    80. this.refreshStatus();
    81. }
    82. refreshStatus(): void {
    83. this.isAllDisplayDataChecked = this.listOfDisplayData
    84. .filter(item => !item.disabled)
    85. .every(item => this.mapOfCheckedId[item.id]);
    86. this.isIndeterminate =
    87. this.listOfDisplayData.filter(item => !item.disabled).some(item => this.mapOfCheckedId[item.id]) &&
    88. !this.isAllDisplayDataChecked;
    89. this.numberOfChecked = this.listOfAllData.filter(item => this.mapOfCheckedId[item.id]).length;
    90. }
    91. checkAll(value: boolean): void {
    92. this.listOfDisplayData.filter(item => !item.disabled).forEach(item => (this.mapOfCheckedId[item.id] = value));
    93. this.refreshStatus();
    94. }
    95. operateData(): void {
    96. this.isOperating = true;
    97. setTimeout(() => {
    98. this.listOfAllData.forEach(item => (this.mapOfCheckedId[item.id] = false));
    99. this.refreshStatus();
    100. this.isOperating = false;
    101. }, 1000);
    102. }
    103. ngOnInit(): void {
    104. for (let i = 0; i < 100; i++) {
    105. this.listOfAllData.push({
    106. id: i,
    107. name: `Edward King ${i}`,
    108. age: 32,
    109. address: `London, Park Lane no. ${i}`,
    110. disabled: i % 2 === 0
    111. });
    112. }
    113. }
    114. }

    Table表格 - 图3

    自定义选择项

    通过 nzShowRowSelectionnzSelections 自定义选择项.

    1. import { Component, OnInit } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-table-row-selection-custom',
    4. template: `
    5. <nz-table
    6. #rowSelectionTable
    7. nzShowSizeChanger
    8. [nzData]="listOfAllData"
    9. (nzCurrentPageDataChange)="currentPageDataChange($event)"
    10. >
    11. <thead>
    12. <tr>
    13. <th
    14. nzShowCheckbox
    15. nzShowRowSelection
    16. [nzSelections]="listOfSelection"
    17. [(nzChecked)]="isAllDisplayDataChecked"
    18. [nzIndeterminate]="isIndeterminate"
    19. (nzCheckedChange)="checkAll($event)"
    20. ></th>
    21. <th>Name</th>
    22. <th>Age</th>
    23. <th>Address</th>
    24. </tr>
    25. </thead>
    26. <tbody>
    27. <tr *ngFor="let data of rowSelectionTable.data">
    28. <td nzShowCheckbox [(nzChecked)]="mapOfCheckedId[data.id]" (nzCheckedChange)="refreshStatus()"></td>
    29. <td>{{ data.name }}</td>
    30. <td>{{ data.age }}</td>
    31. <td>{{ data.address }}</td>
    32. </tr>
    33. </tbody>
    34. </nz-table>
    35. `
    36. })
    37. export class NzDemoTableRowSelectionCustomComponent implements OnInit {
    38. listOfSelection = [
    39. {
    40. text: 'Select All Row',
    41. onSelect: () => {
    42. this.checkAll(true);
    43. }
    44. },
    45. {
    46. text: 'Select Odd Row',
    47. onSelect: () => {
    48. this.listOfDisplayData.forEach((data, index) => (this.mapOfCheckedId[data.id] = index % 2 !== 0));
    49. this.refreshStatus();
    50. }
    51. },
    52. {
    53. text: 'Select Even Row',
    54. onSelect: () => {
    55. this.listOfDisplayData.forEach((data, index) => (this.mapOfCheckedId[data.id] = index % 2 === 0));
    56. this.refreshStatus();
    57. }
    58. }
    59. ];
    60. isAllDisplayDataChecked = false;
    61. isIndeterminate = false;
    62. listOfDisplayData: any[] = [];
    63. listOfAllData: any[] = [];
    64. mapOfCheckedId: { [key: string]: boolean } = {};
    65. currentPageDataChange($event: Array<{ id: number; name: string; age: number; address: string }>): void {
    66. this.listOfDisplayData = $event;
    67. this.refreshStatus();
    68. }
    69. refreshStatus(): void {
    70. this.isAllDisplayDataChecked = this.listOfDisplayData.every(item => this.mapOfCheckedId[item.id]);
    71. this.isIndeterminate =
    72. this.listOfDisplayData.some(item => this.mapOfCheckedId[item.id]) && !this.isAllDisplayDataChecked;
    73. }
    74. checkAll(value: boolean): void {
    75. this.listOfDisplayData.forEach(item => (this.mapOfCheckedId[item.id] = value));
    76. this.refreshStatus();
    77. }
    78. ngOnInit(): void {
    79. for (let i = 0; i < 100; i++) {
    80. this.listOfAllData.push({
    81. id: i,
    82. name: `Edward King ${i}`,
    83. age: 32,
    84. address: `London, Park Lane no. ${i}`
    85. });
    86. }
    87. }
    88. }

    Table表格 - 图4

    筛选和排序

    对某一列数据进行筛选,通过指定 thnzShowFilter 属性来展示筛选菜单, 使用 nzFilters 属性来指定筛选选项,nzFilterChange 用于获取当前选中的选项,nzFilterMultiple 用于指定多选和单选。

    对某一列数据进行排序,通过指定 thnzShowSort 属性来展示排序按钮,使用 nzSortKey 来指定排序的 key,在 thead 上通过 nzSortChange 来获取排序改变事件,通过 nzSingleSort 来指定是否单列排序。

    1. import { Component } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-table-head',
    4. template: `
    5. <nz-table #filterTable [nzData]="listOfDisplayData">
    6. <thead (nzSortChange)="sort($event)" nzSingleSort>
    7. <tr>
    8. <th
    9. nzShowSort
    10. nzSortKey="name"
    11. nzShowFilter
    12. [nzFilters]="listOfName"
    13. (nzFilterChange)="filter($event, searchAddress)"
    14. >
    15. Name
    16. </th>
    17. <th nzShowSort nzSortKey="age">Age</th>
    18. <th
    19. nzShowSort
    20. nzSortKey="address"
    21. nzShowFilter
    22. [nzFilterMultiple]="false"
    23. [nzFilters]="listOfAddress"
    24. (nzFilterChange)="filter(listOfSearchName, $event)"
    25. >
    26. Address
    27. </th>
    28. </tr>
    29. </thead>
    30. <tbody>
    31. <tr *ngFor="let data of filterTable.data">
    32. <td>{{ data.name }}</td>
    33. <td>{{ data.age }}</td>
    34. <td>{{ data.address }}</td>
    35. </tr>
    36. </tbody>
    37. </nz-table>
    38. `
    39. })
    40. export class NzDemoTableHeadComponent {
    41. sortName: string | null = null;
    42. sortValue: string | null = null;
    43. searchAddress: string;
    44. listOfName = [{ text: 'Joe', value: 'Joe' }, { text: 'Jim', value: 'Jim' }];
    45. listOfAddress = [{ text: 'London', value: 'London' }, { text: 'Sidney', value: 'Sidney' }];
    46. listOfSearchName: string[] = [];
    47. listOfData: Array<{ name: string; age: number; address: string; [key: string]: string | number }> = [
    48. {
    49. name: 'John Brown',
    50. age: 32,
    51. address: 'New York No. 1 Lake Park'
    52. },
    53. {
    54. name: 'Jim Green',
    55. age: 42,
    56. address: 'London No. 1 Lake Park'
    57. },
    58. {
    59. name: 'Joe Black',
    60. age: 32,
    61. address: 'Sidney No. 1 Lake Park'
    62. },
    63. {
    64. name: 'Jim Red',
    65. age: 32,
    66. address: 'London No. 2 Lake Park'
    67. }
    68. ];
    69. listOfDisplayData: Array<{ name: string; age: number; address: string; [key: string]: string | number }> = [
    70. ...this.listOfData
    71. ];
    72. sort(sort: { key: string; value: string }): void {
    73. this.sortName = sort.key;
    74. this.sortValue = sort.value;
    75. this.search();
    76. }
    77. filter(listOfSearchName: string[], searchAddress: string): void {
    78. this.listOfSearchName = listOfSearchName;
    79. this.searchAddress = searchAddress;
    80. this.search();
    81. }
    82. search(): void {
    83. /** filter data **/
    84. const filterFunc = (item: { name: string; age: number; address: string }) =>
    85. (this.searchAddress ? item.address.indexOf(this.searchAddress) !== -1 : true) &&
    86. (this.listOfSearchName.length ? this.listOfSearchName.some(name => item.name.indexOf(name) !== -1) : true);
    87. const data = this.listOfData.filter(item => filterFunc(item));
    88. /** sort data **/
    89. if (this.sortName && this.sortValue) {
    90. this.listOfDisplayData = data.sort((a, b) =>
    91. this.sortValue === 'ascend'
    92. ? a[this.sortName!] > b[this.sortName!]
    93. ? 1
    94. : -1
    95. : b[this.sortName!] > a[this.sortName!]
    96. ? 1
    97. : -1
    98. );
    99. } else {
    100. this.listOfDisplayData = data;
    101. }
    102. }
    103. }

    Table表格 - 图5

    默认筛选

    通过设置 filter 对象的 { byDefault: true } 属性来默认启用一个筛选器。注意,你必须同时自行设置过滤后应当展示的列表项,为了保持数据流的清晰和数据的一致性,组件库不会为你做这项工作。详情请见 demo。

    1. import { Component } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-table-default-filter',
    4. template: `
    5. <nz-table #filterTable [nzData]="listOfDisplayData">
    6. <thead (nzSortChange)="sort($event)" nzSingleSort>
    7. <tr>
    8. <th
    9. nzShowSort
    10. nzSortKey="name"
    11. nzShowFilter
    12. [nzFilters]="listOfName"
    13. (nzFilterChange)="filter($event, searchAddress)"
    14. >
    15. Name
    16. </th>
    17. <th nzShowSort nzSortKey="age">Age</th>
    18. <th
    19. nzShowSort
    20. nzSortKey="address"
    21. nzShowFilter
    22. [nzFilterMultiple]="false"
    23. [nzFilters]="listOfAddress"
    24. (nzFilterChange)="filter(listOfSearchName, $event)"
    25. >
    26. Address
    27. </th>
    28. </tr>
    29. </thead>
    30. <tbody>
    31. <tr *ngFor="let data of filterTable.data">
    32. <td>{{ data.name }}</td>
    33. <td>{{ data.age }}</td>
    34. <td>{{ data.address }}</td>
    35. </tr>
    36. </tbody>
    37. </nz-table>
    38. `
    39. })
    40. export class NzDemoTableDefaultFilterComponent {
    41. listOfName = [{ text: 'Joe', value: 'Joe', byDefault: true }, { text: 'Jim', value: 'Jim' }];
    42. listOfAddress = [{ text: 'London', value: 'London', byDefault: true }, { text: 'Sidney', value: 'Sidney' }];
    43. listOfSearchName = ['Joe']; // You need to change it as well!
    44. sortName: string | null = null;
    45. sortValue: string | null = null;
    46. searchAddress = 'London';
    47. listOfData: Array<{ name: string; age: number; address: string; [key: string]: string | number }> = [
    48. {
    49. name: 'John Brown',
    50. age: 32,
    51. address: 'New York No. 1 Lake Park'
    52. },
    53. {
    54. name: 'Jim Green',
    55. age: 42,
    56. address: 'London No. 1 Lake Park'
    57. },
    58. {
    59. name: 'Joe Black',
    60. age: 32,
    61. address: 'Sidney No. 1 Lake Park'
    62. },
    63. {
    64. name: 'Jim Red',
    65. age: 32,
    66. address: 'London No. 2 Lake Park'
    67. }
    68. ];
    69. // You need to change it as well!
    70. listOfDisplayData: Array<{ name: string; age: number; address: string; [key: string]: string | number }> = [];
    71. sort(sort: { key: string; value: string }): void {
    72. this.sortName = sort.key;
    73. this.sortValue = sort.value;
    74. this.search();
    75. }
    76. filter(listOfSearchName: string[], searchAddress: string): void {
    77. console.log(listOfSearchName, searchAddress);
    78. this.listOfSearchName = listOfSearchName;
    79. this.searchAddress = searchAddress;
    80. this.search();
    81. }
    82. search(): void {
    83. /** filter data **/
    84. const filterFunc = (item: { name: string; age: number; address: string }) =>
    85. (this.searchAddress ? item.address.indexOf(this.searchAddress) !== -1 : true) &&
    86. (this.listOfSearchName.length ? this.listOfSearchName.some(name => item.name.indexOf(name) !== -1) : true);
    87. const data = this.listOfData.filter(item => filterFunc(item));
    88. /** sort data **/
    89. if (this.sortName && this.sortValue) {
    90. this.listOfDisplayData = data.sort((a, b) =>
    91. this.sortValue === 'ascend'
    92. ? a[this.sortName!] > b[this.sortName!]
    93. ? 1
    94. : -1
    95. : b[this.sortName!] > a[this.sortName!]
    96. ? 1
    97. : -1
    98. );
    99. } else {
    100. this.listOfDisplayData = data;
    101. }
    102. }
    103. }

    Table表格 - 图6

    可控的筛选和排序

    使用受控属性对筛选状态进行控制。

    1. th 中定义了 nzSort 属性即视为受控模式。
    2. 通过手动指定 nzSort 来指定当前列的排序状态
    3. 通过 thnzSortChange 事件来获取当前列排序状态的改变
    4. 不可与 thead 中的 nzSortChangenzSingleSort 同时使用
    1. import { Component } from '@angular/core';
    2. interface Data {
    3. name: string;
    4. age: number;
    5. address: string;
    6. [key: string]: any;
    7. }
    8. @Component({
    9. selector: 'nz-demo-table-reset-filter',
    10. template: `
    11. <div class="table-operations">
    12. <button nz-button (click)="sort('age', 'descend')">Sort age</button>
    13. <button nz-button (click)="resetFilters()">Clear filters</button>
    14. <button nz-button (click)="resetSortAndFilters()">Clear filters and sorters</button>
    15. </div>
    16. <nz-table #filterTable [nzData]="listOfDisplayData">
    17. <thead>
    18. <tr>
    19. <th
    20. nzShowSort
    21. nzShowFilter
    22. [(nzSort)]="mapOfSort.name"
    23. (nzSortChange)="sort('name', $event)"
    24. [nzFilters]="listOfFilterName"
    25. (nzFilterChange)="search($event, listOfSearchAddress)"
    26. >
    27. Name
    28. </th>
    29. <th nzShowSort [(nzSort)]="mapOfSort.age" (nzSortChange)="sort('age', $event)">Age</th>
    30. <th
    31. nzShowSort
    32. nzShowFilter
    33. [(nzSort)]="mapOfSort.address"
    34. (nzSortChange)="sort('address', $event)"
    35. [nzFilters]="listOfFilterAddress"
    36. (nzFilterChange)="search(listOfSearchName, $event)"
    37. >
    38. Address
    39. </th>
    40. </tr>
    41. </thead>
    42. <tbody>
    43. <tr *ngFor="let data of filterTable.data">
    44. <td>{{ data.name }}</td>
    45. <td>{{ data.age }}</td>
    46. <td>{{ data.address }}</td>
    47. </tr>
    48. </tbody>
    49. </nz-table>
    50. `,
    51. styles: [
    52. `
    53. .table-operations {
    54. margin-bottom: 16px;
    55. }
    56. .table-operations > button {
    57. margin-right: 8px;
    58. }
    59. `
    60. ]
    61. })
    62. export class NzDemoTableResetFilterComponent {
    63. listOfSearchName: string[] = [];
    64. listOfSearchAddress: string[] = [];
    65. listOfFilterName = [{ text: 'Joe', value: 'Joe' }, { text: 'Jim', value: 'Jim' }];
    66. listOfFilterAddress = [{ text: 'London', value: 'London' }, { text: 'Sidney', value: 'Sidney' }];
    67. listOfData: Data[] = [
    68. {
    69. name: 'John Brown',
    70. age: 32,
    71. address: 'New York No. 1 Lake Park'
    72. },
    73. {
    74. name: 'Jim Green',
    75. age: 42,
    76. address: 'London No. 1 Lake Park'
    77. },
    78. {
    79. name: 'Joe Black',
    80. age: 32,
    81. address: 'Sidney No. 1 Lake Park'
    82. },
    83. {
    84. name: 'Jim Red',
    85. age: 32,
    86. address: 'London No. 2 Lake Park'
    87. }
    88. ];
    89. listOfDisplayData = [...this.listOfData];
    90. mapOfSort: { [key: string]: any } = {
    91. name: null,
    92. age: null,
    93. address: null
    94. };
    95. sortName: string | null = null;
    96. sortValue: string | null = null;
    97. sort(sortName: string, value: string): void {
    98. this.sortName = sortName;
    99. this.sortValue = value;
    100. for (const key in this.mapOfSort) {
    101. this.mapOfSort[key] = key === sortName ? value : null;
    102. }
    103. this.search(this.listOfSearchName, this.listOfSearchAddress);
    104. }
    105. search(listOfSearchName: string[], listOfSearchAddress: string[]): void {
    106. this.listOfSearchName = listOfSearchName;
    107. this.listOfSearchAddress = listOfSearchAddress;
    108. const filterFunc = (item: Data) =>
    109. (this.listOfSearchAddress.length
    110. ? this.listOfSearchAddress.some(address => item.address.indexOf(address) !== -1)
    111. : true) &&
    112. (this.listOfSearchName.length ? this.listOfSearchName.some(name => item.name.indexOf(name) !== -1) : true);
    113. const listOfData = this.listOfData.filter((item: Data) => filterFunc(item));
    114. if (this.sortName && this.sortValue) {
    115. this.listOfDisplayData = listOfData.sort((a, b) =>
    116. this.sortValue === 'ascend'
    117. ? a[this.sortName!] > b[this.sortName!]
    118. ? 1
    119. : -1
    120. : b[this.sortName!] > a[this.sortName!]
    121. ? 1
    122. : -1
    123. );
    124. } else {
    125. this.listOfDisplayData = listOfData;
    126. }
    127. }
    128. resetFilters(): void {
    129. this.listOfFilterName = [{ text: 'Joe', value: 'Joe' }, { text: 'Jim', value: 'Jim' }];
    130. this.listOfFilterAddress = [{ text: 'London', value: 'London' }, { text: 'Sidney', value: 'Sidney' }];
    131. this.listOfSearchName = [];
    132. this.listOfSearchAddress = [];
    133. this.search(this.listOfSearchName, this.listOfSearchAddress);
    134. }
    135. resetSortAndFilters(): void {
    136. this.sortName = null;
    137. this.sortValue = null;
    138. this.mapOfSort = {
    139. name: null,
    140. age: null,
    141. address: null
    142. };
    143. this.resetFilters();
    144. this.search(this.listOfSearchName, this.listOfSearchAddress);
    145. }
    146. }

    Table表格 - 图7

    自定义筛选菜单

    通过 nz-dropdownnzFiltersnzFilterChange 定义自定义的列筛选功能,并实现一个搜索列的示例,实际使用中建议将搜索组件进行单独封装。

    1. import { Component } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-table-custom-filter-panel',
    4. template: `
    5. <nz-table #nzTable [nzData]="listOfDisplayData">
    6. <thead>
    7. <tr>
    8. <th nzCustomFilter>
    9. Name
    10. <nz-dropdown nzTrigger="click" nzPlacement="bottomRight" [nzClickHide]="false" nzTableFilter #dropdown>
    11. <i
    12. nz-icon
    13. nzType="search"
    14. class="ant-table-filter-icon"
    15. [class.ant-table-filter-open]="dropdown.nzVisible"
    16. nz-dropdown
    17. ></i>
    18. <div class="search-box">
    19. <input type="text" nz-input placeholder="Search name" [(ngModel)]="searchValue" />
    20. <button nz-button nzSize="small" nzType="primary" (click)="search()" class="search-button">
    21. Search
    22. </button>
    23. <button nz-button nzSize="small" (click)="reset()">Reset</button>
    24. </div>
    25. </nz-dropdown>
    26. </th>
    27. <th>Age</th>
    28. <th nzShowFilter [nzFilters]="listOfFilterAddress" (nzFilterChange)="filterAddressChange($event)">Address</th>
    29. </tr>
    30. </thead>
    31. <tbody>
    32. <tr *ngFor="let data of nzTable.data">
    33. <td>{{ data.name }}</td>
    34. <td>{{ data.age }}</td>
    35. <td>{{ data.address }}</td>
    36. </tr>
    37. </tbody>
    38. </nz-table>
    39. `,
    40. styles: [
    41. `
    42. .search-box {
    43. padding: 8px;
    44. }
    45. .search-box input {
    46. width: 188px;
    47. margin-bottom: 8px;
    48. display: block;
    49. }
    50. .search-box button {
    51. width: 90px;
    52. }
    53. .search-button {
    54. margin-right: 8px;
    55. }
    56. `
    57. ]
    58. })
    59. export class NzDemoTableCustomFilterPanelComponent {
    60. searchValue = '';
    61. sortName: string | null = null;
    62. sortValue: string | null = null;
    63. listOfFilterAddress = [{ text: 'London', value: 'London' }, { text: 'Sidney', value: 'Sidney' }];
    64. listOfSearchAddress: string[] = [];
    65. listOfData: Array<{ name: string; age: number; address: string; [key: string]: string | number }> = [
    66. {
    67. name: 'John Brown',
    68. age: 32,
    69. address: 'New York No. 1 Lake Park'
    70. },
    71. {
    72. name: 'Jim Green',
    73. age: 42,
    74. address: 'London No. 1 Lake Park'
    75. },
    76. {
    77. name: 'Joe Black',
    78. age: 32,
    79. address: 'Sidney No. 1 Lake Park'
    80. },
    81. {
    82. name: 'Jim Red',
    83. age: 32,
    84. address: 'London No. 2 Lake Park'
    85. }
    86. ];
    87. listOfDisplayData = [...this.listOfData];
    88. reset(): void {
    89. this.searchValue = '';
    90. this.search();
    91. }
    92. sort(sortName: string, value: string): void {
    93. this.sortName = sortName;
    94. this.sortValue = value;
    95. this.search();
    96. }
    97. filterAddressChange(value: string[]): void {
    98. this.listOfSearchAddress = value;
    99. this.search();
    100. }
    101. search(): void {
    102. const filterFunc = (item: { name: string; age: number; address: string }) => {
    103. return (
    104. (this.listOfSearchAddress.length
    105. ? this.listOfSearchAddress.some(address => item.address.indexOf(address) !== -1)
    106. : true) && item.name.indexOf(this.searchValue) !== -1
    107. );
    108. };
    109. const data = this.listOfData.filter((item: { name: string; age: number; address: string }) => filterFunc(item));
    110. this.listOfDisplayData = data.sort((a, b) =>
    111. this.sortValue === 'ascend'
    112. ? a[this.sortName!] > b[this.sortName!]
    113. ? 1
    114. : -1
    115. : b[this.sortName!] > a[this.sortName!]
    116. ? 1
    117. : -1
    118. );
    119. }
    120. }

    Table表格 - 图8

    远程加载数据

    这个例子通过简单的 ajax 读取方式,演示了如何从服务端读取并展现数据,具有筛选、排序等功能以及页面 loading 效果。开发者可以自行接入其他数据处理方式。

    注意,此示例使用 模拟接口,展示数据可能不准确,请打开网络面板查看请求。

    1. import { HttpClient, HttpParams } from '@angular/common/http';
    2. import { Component, Injectable, OnInit } from '@angular/core';
    3. import { Observable } from 'rxjs';
    4. @Injectable()
    5. export class RandomUserService {
    6. randomUserUrl = 'https://api.randomuser.me/';
    7. getUsers(
    8. pageIndex: number = 1,
    9. pageSize: number = 10,
    10. sortField: string,
    11. sortOrder: string,
    12. genders: string[]
    13. ): Observable<{}> {
    14. let params = new HttpParams()
    15. .append('page', `${pageIndex}`)
    16. .append('results', `${pageSize}`)
    17. .append('sortField', sortField)
    18. .append('sortOrder', sortOrder);
    19. genders.forEach(gender => {
    20. params = params.append('gender', gender);
    21. });
    22. return this.http.get(`${this.randomUserUrl}`, {
    23. params
    24. });
    25. }
    26. constructor(private http: HttpClient) {}
    27. }
    28. @Component({
    29. selector: 'nz-demo-table-ajax',
    30. providers: [RandomUserService],
    31. template: `
    32. <nz-table
    33. #ajaxTable
    34. nzShowSizeChanger
    35. [nzFrontPagination]="false"
    36. [nzData]="listOfData"
    37. [nzLoading]="loading"
    38. [nzTotal]="total"
    39. [(nzPageIndex)]="pageIndex"
    40. [(nzPageSize)]="pageSize"
    41. (nzPageIndexChange)="searchData()"
    42. (nzPageSizeChange)="searchData(true)"
    43. >
    44. <thead (nzSortChange)="sort($event)" nzSingleSort>
    45. <tr>
    46. <th nzShowSort nzSortKey="name">Name</th>
    47. <th nzShowFilter [nzFilters]="filterGender" (nzFilterChange)="updateFilter($event)">Gender</th>
    48. <th nzShowSort nzSortKey="email"><span>Email</span></th>
    49. </tr>
    50. </thead>
    51. <tbody>
    52. <tr *ngFor="let data of ajaxTable.data">
    53. <td>{{ data.name.first }} {{ data.name.last }}</td>
    54. <td>{{ data.gender }}</td>
    55. <td>{{ data.email }}</td>
    56. </tr>
    57. </tbody>
    58. </nz-table>
    59. `
    60. })
    61. export class NzDemoTableAjaxComponent implements OnInit {
    62. pageIndex = 1;
    63. pageSize = 10;
    64. total = 1;
    65. listOfData = [];
    66. loading = true;
    67. sortValue: string | null = null;
    68. sortKey: string | null = null;
    69. filterGender = [{ text: 'male', value: 'male' }, { text: 'female', value: 'female' }];
    70. searchGenderList: string[] = [];
    71. sort(sort: { key: string; value: string }): void {
    72. this.sortKey = sort.key;
    73. this.sortValue = sort.value;
    74. this.searchData();
    75. }
    76. constructor(private randomUserService: RandomUserService) {}
    77. searchData(reset: boolean = false): void {
    78. if (reset) {
    79. this.pageIndex = 1;
    80. }
    81. this.loading = true;
    82. this.randomUserService
    83. .getUsers(this.pageIndex, this.pageSize, this.sortKey!, this.sortValue!, this.searchGenderList)
    84. .subscribe((data: any) => {
    85. this.loading = false;
    86. this.total = 200;
    87. this.listOfData = data.results;
    88. });
    89. }
    90. updateFilter(value: string[]): void {
    91. this.searchGenderList = value;
    92. this.searchData(true);
    93. }
    94. ngOnInit(): void {
    95. this.searchData();
    96. }
    97. }

    Table表格 - 图9

    紧凑型

    两种紧凑型的列表,小型列表只用于对话框内。

    1. import { Component } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-table-size',
    4. template: `
    5. <h4>Middle size table</h4>
    6. <nz-table #middleTable nzSize="middle" [nzData]="data">
    7. <thead>
    8. <tr>
    9. <th>Name</th>
    10. <th>Age</th>
    11. <th>Address</th>
    12. </tr>
    13. </thead>
    14. <tbody>
    15. <tr *ngFor="let data of middleTable.data">
    16. <td>{{ data.name }}</td>
    17. <td>{{ data.age }}</td>
    18. <td>{{ data.address }}</td>
    19. </tr>
    20. </tbody>
    21. </nz-table>
    22. <h4>Small size table</h4>
    23. <nz-table #smallTable nzSize="small" [nzData]="data">
    24. <thead>
    25. <tr>
    26. <th>Name</th>
    27. <th>Age</th>
    28. <th>Address</th>
    29. </tr>
    30. </thead>
    31. <tbody>
    32. <tr *ngFor="let data of smallTable.data">
    33. <td>{{ data.name }}</td>
    34. <td>{{ data.age }}</td>
    35. <td>{{ data.address }}</td>
    36. </tr>
    37. </tbody>
    38. </nz-table>
    39. `,
    40. styles: [
    41. `
    42. h4 {
    43. margin-bottom: 16px;
    44. }
    45. `
    46. ]
    47. })
    48. export class NzDemoTableSizeComponent {
    49. data = [
    50. {
    51. key: '1',
    52. name: 'John Brown',
    53. age: 32,
    54. address: 'New York No. 1 Lake Park'
    55. },
    56. {
    57. key: '2',
    58. name: 'Jim Green',
    59. age: 42,
    60. address: 'London No. 1 Lake Park'
    61. },
    62. {
    63. key: '3',
    64. name: 'Joe Black',
    65. age: 32,
    66. address: 'Sidney No. 1 Lake Park'
    67. }
    68. ];
    69. }

    Table表格 - 图10

    带边框

    添加表格边框线,页头和页脚。

    1. import { Component } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-table-bordered',
    4. template: `
    5. <nz-table #borderedTable nzBordered nzFooter="Footer" nzTitle="Header" [nzData]="dataSet">
    6. <thead>
    7. <tr>
    8. <th>Name</th>
    9. <th>Age</th>
    10. <th>Address</th>
    11. </tr>
    12. </thead>
    13. <tbody>
    14. <tr *ngFor="let data of borderedTable.data">
    15. <td>{{ data.name }}</td>
    16. <td>{{ data.age }}</td>
    17. <td>{{ data.address }}</td>
    18. </tr>
    19. </tbody>
    20. </nz-table>
    21. `
    22. })
    23. export class NzDemoTableBorderedComponent {
    24. dataSet = [
    25. {
    26. key: '1',
    27. name: 'John Brown',
    28. age: 32,
    29. address: 'New York No. 1 Lake Park'
    30. },
    31. {
    32. key: '2',
    33. name: 'Jim Green',
    34. age: 42,
    35. address: 'London No. 1 Lake Park'
    36. },
    37. {
    38. key: '3',
    39. name: 'Joe Black',
    40. age: 32,
    41. address: 'Sidney No. 1 Lake Park'
    42. }
    43. ];
    44. }

    Table表格 - 图11

    可展开

    当表格内容较多不能一次性完全展示时,可以通过 td 上的 nzExpand 属性展开。

    1. import { Component } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-table-expand',
    4. template: `
    5. <nz-table #nzTable [nzData]="listOfData">
    6. <thead>
    7. <tr>
    8. <th nzShowExpand></th>
    9. <th>Name</th>
    10. <th>Age</th>
    11. <th>Address</th>
    12. </tr>
    13. </thead>
    14. <tbody>
    15. <ng-template ngFor let-data [ngForOf]="nzTable.data">
    16. <tr>
    17. <td nzShowExpand [(nzExpand)]="mapOfExpandData[data.id]"></td>
    18. <td>{{ data.name }}</td>
    19. <td>{{ data.age }}</td>
    20. <td>{{ data.address }}</td>
    21. </tr>
    22. <tr [nzExpand]="mapOfExpandData[data.id]">
    23. <td></td>
    24. <td colspan="3">{{ data.description }}</td>
    25. </tr>
    26. </ng-template>
    27. </tbody>
    28. </nz-table>
    29. `,
    30. styles: []
    31. })
    32. export class NzDemoTableExpandComponent {
    33. mapOfExpandData: { [key: string]: boolean } = {};
    34. listOfData = [
    35. {
    36. id: 1,
    37. name: 'John Brown',
    38. age: 32,
    39. expand: false,
    40. address: 'New York No. 1 Lake Park',
    41. description: 'My name is John Brown, I am 32 years old, living in New York No. 1 Lake Park.'
    42. },
    43. {
    44. id: 2,
    45. name: 'Jim Green',
    46. age: 42,
    47. expand: false,
    48. address: 'London No. 1 Lake Park',
    49. description: 'My name is Jim Green, I am 42 years old, living in London No. 1 Lake Park.'
    50. },
    51. {
    52. id: 3,
    53. name: 'Joe Black',
    54. age: 32,
    55. expand: false,
    56. address: 'Sidney No. 1 Lake Park',
    57. description: 'My name is Joe Black, I am 32 years old, living in Sidney No. 1 Lake Park.'
    58. }
    59. ];
    60. }

    Table表格 - 图12

    表格行/列合并

    W3C标准 <table> 一样,使用 colspanrowspan 合并行/列。

    1. import { Component } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-table-colspan-rowspan',
    4. template: `
    5. <nz-table #colSpanTable [nzData]="listOfData" nzBordered>
    6. <thead>
    7. <tr>
    8. <th>Name</th>
    9. <th>Age</th>
    10. <th colspan="2">Home phone</th>
    11. <th>Address</th>
    12. </tr>
    13. </thead>
    14. <tbody>
    15. <tr *ngFor="let data of colSpanTable.data; index as i">
    16. <td>{{ data.name }}</td>
    17. <td [attr.colspan]="i === 4 ? 5 : 1">{{ data.age }}</td>
    18. <td [attr.rowspan]="i === 2 ? 2 : 1" *ngIf="i !== 3 && i !== 4">{{ data.tel }}</td>
    19. <td *ngIf="i !== 4">{{ data.phone }}</td>
    20. <td *ngIf="i !== 4">{{ data.address }}</td>
    21. </tr>
    22. </tbody>
    23. </nz-table>
    24. `
    25. })
    26. export class NzDemoTableColspanRowspanComponent {
    27. listOfData = [
    28. {
    29. key: '1',
    30. name: 'John Brown',
    31. age: 32,
    32. tel: '0571-22098909',
    33. phone: 18889898989,
    34. address: 'New York No. 1 Lake Park'
    35. },
    36. {
    37. key: '2',
    38. name: 'Jim Green',
    39. tel: '0571-22098333',
    40. phone: 18889898888,
    41. age: 42,
    42. address: 'London No. 1 Lake Park'
    43. },
    44. {
    45. key: '3',
    46. name: 'Joe Black',
    47. age: 32,
    48. tel: '0575-22098909',
    49. phone: 18900010002,
    50. address: 'Sidney No. 1 Lake Park'
    51. },
    52. {
    53. key: '4',
    54. name: 'Jim Red',
    55. age: 18,
    56. tel: '0575-22098909',
    57. phone: 18900010002,
    58. address: 'London No. 2 Lake Park'
    59. },
    60. {
    61. key: '5',
    62. name: 'Jake White',
    63. age: 18,
    64. tel: '0575-22098909',
    65. phone: 18900010002,
    66. address: 'Dublin No. 2 Lake Park'
    67. }
    68. ];
    69. }

    Table表格 - 图13

    树形数据展示

    表格支持树形数据的展示,可以通过设置 nzIndentSize 以控制每一层的缩进宽度,本例子中提供了树与数组之间的转换函数,实际业务中请根据需求修改。

    1. import { Component, OnInit } from '@angular/core';
    2. export interface TreeNodeInterface {
    3. key: number;
    4. name: string;
    5. age: number;
    6. level: number;
    7. expand: boolean;
    8. address: string;
    9. children?: TreeNodeInterface[];
    10. }
    11. @Component({
    12. selector: 'nz-demo-table-expand-children',
    13. template: `
    14. <nz-table #expandTable [nzData]="listOfMapData">
    15. <thead>
    16. <tr>
    17. <th nzWidth="40%">Name</th>
    18. <th nzWidth="30%">Age</th>
    19. <th>Address</th>
    20. </tr>
    21. </thead>
    22. <tbody>
    23. <ng-container *ngFor="let data of expandTable.data">
    24. <ng-container *ngFor="let item of mapOfExpandedData[data.key]">
    25. <tr *ngIf="(item.parent && item.parent.expand) || !item.parent">
    26. <td
    27. [nzIndentSize]="item.level * 20"
    28. [nzShowExpand]="!!item.children"
    29. [(nzExpand)]="item.expand"
    30. (nzExpandChange)="collapse(mapOfExpandedData[data.key], item, $event)"
    31. >
    32. {{ item.name }}
    33. </td>
    34. <td>{{ item.age }}</td>
    35. <td>{{ item.address }}</td>
    36. </tr>
    37. </ng-container>
    38. </ng-container>
    39. </tbody>
    40. </nz-table>
    41. `
    42. })
    43. export class NzDemoTableExpandChildrenComponent implements OnInit {
    44. listOfMapData = [
    45. {
    46. key: 1,
    47. name: 'John Brown sr.',
    48. age: 60,
    49. address: 'New York No. 1 Lake Park',
    50. children: [
    51. {
    52. key: 11,
    53. name: 'John Brown',
    54. age: 42,
    55. address: 'New York No. 2 Lake Park'
    56. },
    57. {
    58. key: 12,
    59. name: 'John Brown jr.',
    60. age: 30,
    61. address: 'New York No. 3 Lake Park',
    62. children: [
    63. {
    64. key: 121,
    65. name: 'Jimmy Brown',
    66. age: 16,
    67. address: 'New York No. 3 Lake Park'
    68. }
    69. ]
    70. },
    71. {
    72. key: 13,
    73. name: 'Jim Green sr.',
    74. age: 72,
    75. address: 'London No. 1 Lake Park',
    76. children: [
    77. {
    78. key: 131,
    79. name: 'Jim Green',
    80. age: 42,
    81. address: 'London No. 2 Lake Park',
    82. children: [
    83. {
    84. key: 1311,
    85. name: 'Jim Green jr.',
    86. age: 25,
    87. address: 'London No. 3 Lake Park'
    88. },
    89. {
    90. key: 1312,
    91. name: 'Jimmy Green sr.',
    92. age: 18,
    93. address: 'London No. 4 Lake Park'
    94. }
    95. ]
    96. }
    97. ]
    98. }
    99. ]
    100. },
    101. {
    102. key: 2,
    103. name: 'Joe Black',
    104. age: 32,
    105. address: 'Sidney No. 1 Lake Park'
    106. }
    107. ];
    108. mapOfExpandedData: { [key: string]: TreeNodeInterface[] } = {};
    109. collapse(array: TreeNodeInterface[], data: TreeNodeInterface, $event: boolean): void {
    110. if ($event === false) {
    111. if (data.children) {
    112. data.children.forEach(d => {
    113. const target = array.find(a => a.key === d.key)!;
    114. target.expand = false;
    115. this.collapse(array, target, false);
    116. });
    117. } else {
    118. return;
    119. }
    120. }
    121. }
    122. convertTreeToList(root: object): TreeNodeInterface[] {
    123. const stack: any[] = [];
    124. const array: any[] = [];
    125. const hashMap = {};
    126. stack.push({ ...root, level: 0, expand: false });
    127. while (stack.length !== 0) {
    128. const node = stack.pop();
    129. this.visitNode(node, hashMap, array);
    130. if (node.children) {
    131. for (let i = node.children.length - 1; i >= 0; i--) {
    132. stack.push({ ...node.children[i], level: node.level + 1, expand: false, parent: node });
    133. }
    134. }
    135. }
    136. return array;
    137. }
    138. visitNode(node: TreeNodeInterface, hashMap: { [key: string]: any }, array: TreeNodeInterface[]): void {
    139. if (!hashMap[node.key]) {
    140. hashMap[node.key] = true;
    141. array.push(node);
    142. }
    143. }
    144. ngOnInit(): void {
    145. this.listOfMapData.forEach(item => {
    146. this.mapOfExpandedData[item.key] = this.convertTreeToList(item);
    147. });
    148. }
    149. }

    Table表格 - 图14

    固定表头

    方便一页内展示大量数据。

    需要指定 thnzWidth 属性,否则列头和内容可能不对齐。

    1. import { Component, OnInit } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-table-fixed-header',
    4. template: `
    5. <nz-table #headerTable [nzData]="listOfData" [nzPageSize]="50" [nzScroll]="{ y: '240px' }">
    6. <thead>
    7. <tr>
    8. <th nzWidth="150px">Name</th>
    9. <th nzWidth="150px">Age</th>
    10. <th>Address</th>
    11. </tr>
    12. </thead>
    13. <tbody>
    14. <tr *ngFor="let data of headerTable.data">
    15. <td>{{ data.name }}</td>
    16. <td>{{ data.age }}</td>
    17. <td>{{ data.address }}</td>
    18. </tr>
    19. </tbody>
    20. </nz-table>
    21. `
    22. })
    23. export class NzDemoTableFixedHeaderComponent implements OnInit {
    24. listOfData: any[] = [];
    25. ngOnInit(): void {
    26. for (let i = 0; i < 100; i++) {
    27. this.listOfData.push({
    28. name: `Edward King ${i}`,
    29. age: 32,
    30. address: `London, Park Lane no. ${i}`
    31. });
    32. }
    33. }
    34. }

    Table表格 - 图15

    固定列

    对于列数很多的数据,可以使用 nzLeftnzRight 固定前后的列,横向滚动查看其它数据,需要和 nzScroll.x 配合使用。

    固定列使用了 sticky 属性,浏览器支持情况可以参考这里。

    若列头与内容不对齐或出现列重复,请指定每一列的 th 的宽度 nzWidth

    建议指定 nzScroll.x 为大于表格宽度的固定值或百分比。注意,且非固定列宽度之和不要超过 nzScroll.x

    1. import { Component } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-table-fixed-columns',
    4. template: `
    5. <nz-table #columnTable [nzData]="listOfData" [nzScroll]="{ x: '1100px' }">
    6. <thead>
    7. <tr>
    8. <th nzWidth="100px" nzLeft="0px">Full Name</th>
    9. <th nzWidth="100px" nzLeft="100px">Age</th>
    10. <th nzWidth="100px">Column 1</th>
    11. <th nzWidth="100px">Column 2</th>
    12. <th nzWidth="100px">Column 3</th>
    13. <th nzWidth="100px">Column 4</th>
    14. <th nzWidth="100px">Column 5</th>
    15. <th nzWidth="100px">Column 6</th>
    16. <th nzWidth="100px">Column 7</th>
    17. <th nzRight="100px" nzWidth="100px">Column 8</th>
    18. <th nzWidth="100px" nzRight="0px">Action</th>
    19. </tr>
    20. </thead>
    21. <tbody>
    22. <tr *ngFor="let data of columnTable.data">
    23. <td nzLeft="0px">{{ data.name }}</td>
    24. <td nzLeft="100px">{{ data.age }}</td>
    25. <td>{{ data.address }}</td>
    26. <td>{{ data.address }}</td>
    27. <td>{{ data.address }}</td>
    28. <td>{{ data.address }}</td>
    29. <td>{{ data.address }}</td>
    30. <td>{{ data.address }}</td>
    31. <td>{{ data.address }}</td>
    32. <td nzRight="100px">{{ data.address }}</td>
    33. <td nzRight="0px">
    34. <a>action</a>
    35. </td>
    36. </tr>
    37. </tbody>
    38. </nz-table>
    39. `
    40. })
    41. export class NzDemoTableFixedColumnsComponent {
    42. listOfData = [
    43. {
    44. key: '1',
    45. name: 'John Brown',
    46. age: 32,
    47. address: 'New York'
    48. },
    49. {
    50. key: '2',
    51. name: 'Jim Green',
    52. age: 40,
    53. address: 'London'
    54. }
    55. ];
    56. }

    Table表格 - 图16

    固定头和列

    适合同时展示有大量数据和数据列。

    固定列使用了 sticky 属性,浏览器支持情况可以参考这里。

    若列头与内容不对齐或出现列重复,请指定列的宽度 nzWidth

    建议指定 nzScroll.x 为大于表格宽度的固定值或百分比。注意,且非固定列宽度之和不要超过 nzScroll.x

    1. import { Component, OnInit } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-table-fixed-columns-header',
    4. template: `
    5. <nz-table #fixedTable [nzData]="listOfData" [nzScroll]="{ x: '1150px', y: '240px' }">
    6. <thead>
    7. <tr>
    8. <th nzWidth="150px" nzLeft="0px">Full Name</th>
    9. <th nzWidth="100px" nzLeft="150px">Age</th>
    10. <th nzWidth="100px">Column 1</th>
    11. <th nzWidth="100px">Column 2</th>
    12. <th nzWidth="100px">Column 3</th>
    13. <th nzWidth="100px">Column 4</th>
    14. <th nzWidth="100px">Column 5</th>
    15. <th nzWidth="100px">Column 6</th>
    16. <th nzWidth="100px">Column 7</th>
    17. <th nzWidth="100px">Column 8</th>
    18. <th nzWidth="100px" nzRight="0px">Action</th>
    19. </tr>
    20. </thead>
    21. <tbody>
    22. <tr *ngFor="let data of fixedTable.data">
    23. <td nzLeft="0px">{{ data.name }}</td>
    24. <td nzLeft="150px">{{ data.age }}</td>
    25. <td>{{ data.address }}</td>
    26. <td>{{ data.address }}</td>
    27. <td>{{ data.address }}</td>
    28. <td>{{ data.address }}</td>
    29. <td>{{ data.address }}</td>
    30. <td>{{ data.address }}</td>
    31. <td>{{ data.address }}</td>
    32. <td>{{ data.address }}</td>
    33. <td nzRight="0px">
    34. <a>action</a>
    35. </td>
    36. </tr>
    37. </tbody>
    38. </nz-table>
    39. `
    40. })
    41. export class NzDemoTableFixedColumnsHeaderComponent implements OnInit {
    42. listOfData: any[] = [];
    43. ngOnInit(): void {
    44. for (let i = 0; i < 100; i++) {
    45. this.listOfData.push({
    46. name: `Edward King ${i}`,
    47. age: 32,
    48. address: `London`
    49. });
    50. }
    51. }
    52. }

    Table表格 - 图17

    表头分组

    当使用分组表头时,thnzWidth 方式不再适用,使用 nzWidthConfig 来设定每个分组的宽度

    1. import { Component, OnInit } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-table-grouping-columns',
    4. template: `
    5. <nz-table
    6. #groupingTable
    7. [nzData]="listOfDisplayData"
    8. nzBordered
    9. nzSize="middle"
    10. [nzWidthConfig]="widthConfig"
    11. [nzScroll]="scrollConfig"
    12. >
    13. <thead>
    14. <tr>
    15. <th rowspan="4" nzLeft="0px" nzShowFilter [nzFilters]="filterName" (nzFilterChange)="search($event)">Name</th>
    16. <th colspan="4">Other</th>
    17. <th colspan="2">Company</th>
    18. <th rowspan="4" nzRight="0px">Gender</th>
    19. </tr>
    20. <tr>
    21. <th rowspan="3" nzShowSort [(nzSort)]="sortValue" (nzSortChange)="search(searchName)">Age</th>
    22. <th colspan="3">Address</th>
    23. <th rowspan="3">Company Address</th>
    24. <th rowspan="3">Company Name</th>
    25. </tr>
    26. <tr>
    27. <th rowspan="2">Street</th>
    28. <th colspan="2">Block</th>
    29. </tr>
    30. <tr>
    31. <th>Building</th>
    32. <th>Door No.</th>
    33. </tr>
    34. </thead>
    35. <tbody>
    36. <tr *ngFor="let data of groupingTable.data">
    37. <td nzLeft="0px">{{ data.name }}</td>
    38. <td>{{ data.age }}</td>
    39. <td>{{ data.street }}</td>
    40. <td>{{ data.building }}</td>
    41. <td>{{ data.number }}</td>
    42. <td>{{ data.companyAddress }}</td>
    43. <td>{{ data.companyName }}</td>
    44. <td nzRight="0px">{{ data.gender }}</td>
    45. </tr>
    46. </tbody>
    47. </nz-table>
    48. `
    49. })
    50. export class NzDemoTableGroupingColumnsComponent implements OnInit {
    51. widthConfig = ['100px', '200px', '200px', '100px', '100px', '200px', '200px', '100px'];
    52. scrollConfig = { x: '1200px', y: '240px' };
    53. listOfDisplayData: any[] = [];
    54. listOfData: any[] = [];
    55. sortValue: string | null = null;
    56. filterName = [{ text: 'Joe', value: 'Joe' }, { text: 'John', value: 'John' }];
    57. searchName: string[] = [];
    58. search(searchName: string[]): void {
    59. this.searchName = searchName;
    60. const filterFunc = (item: any) => {
    61. return this.searchName.length ? this.searchName.some(name => item.name.indexOf(name) !== -1) : true;
    62. };
    63. const listOfData = this.listOfData.filter(item => filterFunc(item));
    64. this.listOfDisplayData = listOfData.sort((a, b) =>
    65. this.sortValue === 'ascend' ? (a.age > b.age ? 1 : -1) : b.age > a.age ? 1 : -1
    66. );
    67. }
    68. ngOnInit(): void {
    69. for (let i = 0; i < 100; i++) {
    70. this.listOfData.push({
    71. name: 'John Brown',
    72. age: i + 1,
    73. street: 'Lake Park',
    74. building: 'C',
    75. number: 2035,
    76. companyAddress: 'Lake Street 42',
    77. companyName: 'SoftLake Co',
    78. gender: 'M'
    79. });
    80. }
    81. this.listOfDisplayData = [...this.listOfData];
    82. }
    83. }

    Table表格 - 图18

    可编辑单元格

    定制带单元格编辑功能的表格,自由操作单元格内容。

    1. import { Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core';
    2. import { NzInputDirective } from 'ng-zorro-antd';
    3. @Component({
    4. selector: 'nz-demo-table-edit-cell',
    5. template: `
    6. <button nz-button (click)="addRow()" nzType="primary">Add</button>
    7. <nz-table #editRowTable nzBordered [nzData]="listOfData">
    8. <thead>
    9. <tr>
    10. <th nzWidth="30%">Name</th>
    11. <th>Age</th>
    12. <th>Address</th>
    13. <th>Action</th>
    14. </tr>
    15. </thead>
    16. <tbody>
    17. <tr *ngFor="let data of editRowTable.data" class="editable-row">
    18. <td>
    19. <div class="editable-cell" *ngIf="editId !== data.id; else editTpl">
    20. <div class="editable-cell-value-wrap" (click)="startEdit(data.id, $event)">
    21. {{ data.name }}
    22. </div>
    23. </div>
    24. <ng-template #editTpl>
    25. <input type="text" nz-input [(ngModel)]="data.name" />
    26. </ng-template>
    27. </td>
    28. <td>{{ data.age }}</td>
    29. <td>{{ data.address }}</td>
    30. <td>
    31. <a nz-popconfirm nzTitle="Sure to delete?" (nzOnConfirm)="deleteRow(data.id)">Delete</a>
    32. </td>
    33. </tr>
    34. </tbody>
    35. </nz-table>
    36. `,
    37. styles: [
    38. `
    39. button {
    40. margin-bottom: 16px;
    41. }
    42. .editable-cell {
    43. position: relative;
    44. }
    45. .editable-cell-value-wrap {
    46. padding: 5px 12px;
    47. cursor: pointer;
    48. }
    49. .editable-row:hover .editable-cell-value-wrap {
    50. border: 1px solid #d9d9d9;
    51. border-radius: 4px;
    52. padding: 4px 11px;
    53. }
    54. `
    55. ]
    56. })
    57. export class NzDemoTableEditCellComponent implements OnInit {
    58. i = 0;
    59. editId: string | null;
    60. listOfData: any[] = [];
    61. @ViewChild(NzInputDirective, { read: ElementRef }) inputElement: ElementRef;
    62. @HostListener('window:click', ['$event'])
    63. handleClick(e: MouseEvent): void {
    64. if (this.editId && this.inputElement && this.inputElement.nativeElement !== e.target) {
    65. this.editId = null;
    66. }
    67. }
    68. addRow(): void {
    69. this.listOfData = [
    70. ...this.listOfData,
    71. {
    72. id: `${this.i}`,
    73. name: `Edward King ${this.i}`,
    74. age: '32',
    75. address: `London, Park Lane no. ${this.i}`
    76. }
    77. ];
    78. this.i++;
    79. }
    80. deleteRow(id: string): void {
    81. this.listOfData = this.listOfData.filter(d => d.id !== id);
    82. }
    83. startEdit(id: string, event: MouseEvent): void {
    84. event.preventDefault();
    85. event.stopPropagation();
    86. this.editId = id;
    87. }
    88. ngOnInit(): void {
    89. this.addRow();
    90. this.addRow();
    91. }
    92. }

    Table表格 - 图19

    可编辑行

    定制带行编辑功能的表格,自由操作行内容。

    1. import { Component, OnInit } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-table-edit-row',
    4. template: `
    5. <nz-table #editRowTable nzBordered [nzData]="listOfData">
    6. <thead>
    7. <tr>
    8. <th nzWidth="25%">Name</th>
    9. <th nzWidth="15%">Age</th>
    10. <th nzWidth="40%">Address</th>
    11. <th>Action</th>
    12. </tr>
    13. </thead>
    14. <tbody>
    15. <tr *ngFor="let data of editRowTable.data">
    16. <td>
    17. <ng-container *ngIf="!editCache[data.id].edit; else nameInputTpl">
    18. {{ data.name }}
    19. </ng-container>
    20. <ng-template #nameInputTpl>
    21. <input type="text" nz-input [(ngModel)]="editCache[data.id].data.name" />
    22. </ng-template>
    23. </td>
    24. <td>
    25. <ng-container *ngIf="!editCache[data.id].edit; else ageInputTpl">
    26. {{ data.age }}
    27. </ng-container>
    28. <ng-template #ageInputTpl>
    29. <input type="text" nz-input [(ngModel)]="editCache[data.id].data.age" />
    30. </ng-template>
    31. </td>
    32. <td>
    33. <ng-container *ngIf="!editCache[data.id].edit; else addressInputTpl">
    34. {{ data.address }}
    35. </ng-container>
    36. <ng-template #addressInputTpl>
    37. <input type="text" nz-input [(ngModel)]="editCache[data.id].data.address" />
    38. </ng-template>
    39. </td>
    40. <td>
    41. <div class="editable-row-operations">
    42. <ng-container *ngIf="!editCache[data.id].edit; else saveTpl">
    43. <a (click)="startEdit(data.id)">Edit</a>
    44. </ng-container>
    45. <ng-template #saveTpl>
    46. <a (click)="saveEdit(data.id)">Save</a>
    47. <a nz-popconfirm nzTitle="Sure to cancel?" (nzOnConfirm)="cancelEdit(data.id)">Cancel</a>
    48. </ng-template>
    49. </div>
    50. </td>
    51. </tr>
    52. </tbody>
    53. </nz-table>
    54. `,
    55. styles: [
    56. `
    57. .editable-row-operations a {
    58. margin-right: 8px;
    59. }
    60. `
    61. ]
    62. })
    63. export class NzDemoTableEditRowComponent implements OnInit {
    64. editCache: { [key: string]: any } = {};
    65. listOfData: any[] = [];
    66. startEdit(id: string): void {
    67. this.editCache[id].edit = true;
    68. }
    69. cancelEdit(id: string): void {
    70. const index = this.listOfData.findIndex(item => item.id === id);
    71. this.editCache[id] = {
    72. data: { ...this.listOfData[index] },
    73. edit: false
    74. };
    75. }
    76. saveEdit(id: string): void {
    77. const index = this.listOfData.findIndex(item => item.id === id);
    78. Object.assign(this.listOfData[index], this.editCache[id].data);
    79. this.editCache[id].edit = false;
    80. }
    81. updateEditCache(): void {
    82. this.listOfData.forEach(item => {
    83. this.editCache[item.id] = {
    84. edit: false,
    85. data: { ...item }
    86. };
    87. });
    88. }
    89. ngOnInit(): void {
    90. for (let i = 0; i < 100; i++) {
    91. this.listOfData.push({
    92. id: `${i}`,
    93. name: `Edrward ${i}`,
    94. age: 32,
    95. address: `London Park no. ${i}`
    96. });
    97. }
    98. this.updateEditCache();
    99. }
    100. }

    Table表格 - 图20

    嵌套子表格

    展示每行数据更详细的信息。

    1. import { Component, OnInit } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-table-nested-table',
    4. template: `
    5. <nz-table #nestedTable [nzData]="listOfParentData" [nzPageSize]="10">
    6. <thead>
    7. <tr>
    8. <th nzShowExpand></th>
    9. <th>Name</th>
    10. <th>Platform</th>
    11. <th>Version</th>
    12. <th>Upgraded</th>
    13. <th>Creator</th>
    14. <th>Date</th>
    15. <th>Action</th>
    16. </tr>
    17. </thead>
    18. <tbody>
    19. <ng-template ngFor let-data [ngForOf]="nestedTable.data">
    20. <tr>
    21. <td nzShowExpand [(nzExpand)]="data.expand"></td>
    22. <td>{{ data.name }}</td>
    23. <td>{{ data.platform }}</td>
    24. <td>{{ data.version }}</td>
    25. <td>{{ data.upgradeNum }}</td>
    26. <td>{{ data.creator }}</td>
    27. <td>{{ data.createdAt }}</td>
    28. <td>
    29. <a>Publish</a>
    30. </td>
    31. </tr>
    32. <tr [nzExpand]="data.expand">
    33. <td></td>
    34. <td colspan="7">
    35. <nz-table #innerTable [nzData]="listOfChildrenData" nzSize="middle" [nzShowPagination]="false">
    36. <thead>
    37. <tr>
    38. <th>Date</th>
    39. <th>Name</th>
    40. <th>Status</th>
    41. <th>Upgrade Status</th>
    42. <th>Action</th>
    43. </tr>
    44. </thead>
    45. <tbody>
    46. <tr *ngFor="let data of innerTable.data">
    47. <td>{{ data.date }}</td>
    48. <td>{{ data.name }}</td>
    49. <td>
    50. <nz-badge [nzStatus]="'success'" [nzText]="'Finished'"></nz-badge>
    51. </td>
    52. <td>{{ data.upgradeNum }}</td>
    53. <td>
    54. <span class="table-operation">
    55. <nz-dropdown>
    56. <a nz-dropdown class="operation"> Pause <i nz-icon type="down"></i> </a>
    57. <ul nz-menu>
    58. <li nz-menu-item>
    59. <a>Action 1</a>
    60. </li>
    61. <li nz-menu-item>
    62. <a>Action 2</a>
    63. </li>
    64. </ul>
    65. </nz-dropdown>
    66. <nz-divider nzType="vertical"></nz-divider>
    67. <a class="operation">Stop</a>
    68. <nz-divider nzType="vertical"></nz-divider>
    69. <a>More</a>
    70. </span>
    71. </td>
    72. </tr>
    73. </tbody>
    74. </nz-table>
    75. </td>
    76. </tr>
    77. </ng-template>
    78. </tbody>
    79. </nz-table>
    80. `
    81. })
    82. export class NzDemoTableNestedTableComponent implements OnInit {
    83. listOfParentData: any[] = [];
    84. listOfChildrenData: any[] = [];
    85. ngOnInit(): void {
    86. for (let i = 0; i < 3; ++i) {
    87. this.listOfParentData.push({
    88. key: i,
    89. name: 'Screem',
    90. platform: 'iOS',
    91. version: '10.3.4.5654',
    92. upgradeNum: 500,
    93. creator: 'Jack',
    94. createdAt: '2014-12-24 23:12:00',
    95. expand: false
    96. });
    97. }
    98. for (let i = 0; i < 3; ++i) {
    99. this.listOfChildrenData.push({
    100. key: i,
    101. date: '2014-12-24 23:12:00',
    102. name: 'This is production name',
    103. upgradeNum: 'Upgraded: 56'
    104. });
    105. }
    106. }
    107. }

    Table表格 - 图21

    虚拟滚动

    虚拟滚动,结合 cdk scrolling 的虚拟滚动,用于巨量数据加载。可以通过获得 cdkVirtualScrollViewport 进行进一步操作,见本示例及 API。

    1. import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
    2. import { NzTableComponent } from 'ng-zorro-antd';
    3. import { Subject } from 'rxjs';
    4. import { takeUntil } from 'rxjs/operators';
    5. @Component({
    6. selector: 'nz-demo-table-virtual',
    7. template: `
    8. <button nz-button (click)="scrollToIndex(200)">Scroll To Index 200</button>
    9. <br />
    10. <br />
    11. <nz-table
    12. #virtualTable
    13. nzVirtualScroll
    14. [nzVirtualItemSize]="54"
    15. [nzData]="listOfData"
    16. [nzFrontPagination]="false"
    17. [nzShowPagination]="false"
    18. [nzScroll]="{ x: '1300px', y: '240px' }"
    19. >
    20. <thead>
    21. <tr>
    22. <th nzWidth="200px" nzLeft="0px">Full Name</th>
    23. <th nzWidth="100px" nzLeft="200px">Age</th>
    24. <th nzWidth="100px">Index</th>
    25. <th nzWidth="100px">Column 1</th>
    26. <th nzWidth="100px">Column 2</th>
    27. <th nzWidth="100px">Column 3</th>
    28. <th nzWidth="100px">Column 4</th>
    29. <th nzWidth="100px">Column 5</th>
    30. <th nzWidth="100px">Column 6</th>
    31. <th nzWidth="100px">Column 7</th>
    32. <th nzWidth="100px">Column 8</th>
    33. <th nzWidth="100px" nzRight="0px">Action</th>
    34. </tr>
    35. </thead>
    36. <tbody>
    37. <ng-template nz-virtual-scroll let-data let-index="index">
    38. <tr>
    39. <td nzLeft="0px">{{ data.name }} {{ index }}</td>
    40. <td nzLeft="200px">{{ data.age }}</td>
    41. <td>{{ data.index }}</td>
    42. <td>{{ data.address }}</td>
    43. <td>{{ data.address }}</td>
    44. <td>{{ data.address }}</td>
    45. <td>{{ data.address }}</td>
    46. <td>{{ data.address }}</td>
    47. <td>{{ data.address }}</td>
    48. <td>{{ data.address }}</td>
    49. <td>{{ data.address }}</td>
    50. <td nzRight="0px">
    51. <a>action</a>
    52. </td>
    53. </tr>
    54. </ng-template>
    55. </tbody>
    56. </nz-table>
    57. `
    58. })
    59. export class NzDemoTableVirtualComponent implements OnInit, AfterViewInit, OnDestroy {
    60. @ViewChild('virtualTable') nzTableComponent: NzTableComponent;
    61. private destroy$ = new Subject();
    62. listOfData: any[] = [];
    63. scrollToIndex(index: number): void {
    64. this.nzTableComponent.cdkVirtualScrollViewport.scrollToIndex(index);
    65. }
    66. ngOnInit(): void {
    67. for (let i = 0; i < 20000; i++) {
    68. this.listOfData.push({
    69. index: i,
    70. name: `Edward King`,
    71. age: 32,
    72. address: `London`
    73. });
    74. }
    75. }
    76. ngAfterViewInit(): void {
    77. this.nzTableComponent.cdkVirtualScrollViewport.scrolledIndexChange
    78. .pipe(takeUntil(this.destroy$))
    79. .subscribe(data => {
    80. console.log('scroll index to', data);
    81. });
    82. }
    83. ngOnDestroy(): void {
    84. this.destroy$.next();
    85. this.destroy$.complete();
    86. }
    87. }

    Table表格 - 图22

    拖拽排序

    使用自定义元素,我们可以集成 cdk drag-drop 来实现拖拽排序。

    1. import { moveItemInArray, CdkDragDrop } from '@angular/cdk/drag-drop';
    2. import { Component } from '@angular/core';
    3. @Component({
    4. selector: 'nz-demo-table-drag-sorting',
    5. template: `
    6. <nz-table [nzData]="listOfData" [nzFrontPagination]="false" [nzShowPagination]="false">
    7. <thead>
    8. <tr>
    9. <th>Name</th>
    10. <th>Age</th>
    11. <th>Address</th>
    12. </tr>
    13. </thead>
    14. <tbody cdkDropList (cdkDropListDropped)="drop($event)">
    15. <tr *ngFor="let data of listOfData" cdkDrag>
    16. <td>{{ data.name }}</td>
    17. <td>{{ data.age }}</td>
    18. <td>{{ data.address }}</td>
    19. </tr>
    20. </tbody>
    21. </nz-table>
    22. `,
    23. styles: [
    24. `
    25. ::ng-deep .cdk-drag-preview {
    26. display: table;
    27. }
    28. ::ng-deep .cdk-drag-placeholder {
    29. opacity: 0;
    30. }
    31. `
    32. ]
    33. })
    34. export class NzDemoTableDragSortingComponent {
    35. listOfData = [
    36. {
    37. key: '1',
    38. name: 'John Brown',
    39. age: 32,
    40. address: 'New York No. 1 Lake Park'
    41. },
    42. {
    43. key: '2',
    44. name: 'Jim Green',
    45. age: 42,
    46. address: 'London No. 1 Lake Park'
    47. },
    48. {
    49. key: '3',
    50. name: 'Joe Black',
    51. age: 32,
    52. address: 'Sidney No. 1 Lake Park'
    53. }
    54. ];
    55. drop(event: CdkDragDrop<string[]>): void {
    56. moveItemInArray(this.listOfData, event.previousIndex, event.currentIndex);
    57. }
    58. }

    Table表格 - 图23

    模板用法

    模板模式,显示内容仅由模板内容控制,不再需要向 nzData 传入数据,完全像普通 table 一样使用,使用 ant-design 的样式。

    1. import { Component } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-table-template',
    4. template: `
    5. <nz-table nzTemplateMode>
    6. <thead>
    7. <tr>
    8. <th>Company</th>
    9. <th>Contact</th>
    10. <th>Country</th>
    11. </tr>
    12. </thead>
    13. <tbody>
    14. <tr>
    15. <td>Alfreds Futterkiste</td>
    16. <td>Maria Anders</td>
    17. <td>Germany</td>
    18. </tr>
    19. <tr>
    20. <td>Centro comercial Moctezuma</td>
    21. <td>Francisco Chang</td>
    22. <td>Mexico</td>
    23. </tr>
    24. <tr>
    25. <td>Ernst Handel</td>
    26. <td>Roland Mendel</td>
    27. <td>Austria</td>
    28. </tr>
    29. <tr>
    30. <td>Island Trading</td>
    31. <td>Helen Bennett</td>
    32. <td>UK</td>
    33. </tr>
    34. <tr>
    35. <td>Laughing Bacchus Winecellars</td>
    36. <td>Yoshi Tannamuri</td>
    37. <td>Canada</td>
    38. </tr>
    39. <tr>
    40. <td>Magazzini Alimentari Riuniti</td>
    41. <td>Giovanni Rovelli</td>
    42. <td>Italy</td>
    43. </tr>
    44. </tbody>
    45. </nz-table>
    46. `
    47. })
    48. export class NzDemoTableTemplateComponent {}

    Table表格 - 图24

    动态控制表格属性

    选择不同配置组合查看效果。

    1. import { Component, OnInit } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-table-dynamic-settings',
    4. template: `
    5. <div class="components-table-demo-control-bar">
    6. <form nz-form nzLayout="inline">
    7. <nz-form-item>
    8. <nz-form-label><label>Bordered</label></nz-form-label>
    9. <nz-form-control><nz-switch [(ngModel)]="bordered" name="bordered"></nz-switch></nz-form-control>
    10. </nz-form-item>
    11. <nz-form-item>
    12. <nz-form-label><label>Loading</label></nz-form-label>
    13. <nz-form-control><nz-switch [(ngModel)]="loading" name="loading"></nz-switch></nz-form-control>
    14. </nz-form-item>
    15. <nz-form-item>
    16. <nz-form-label><label>Pagination</label></nz-form-label>
    17. <nz-form-control><nz-switch [(ngModel)]="pagination" name="pagination"></nz-switch></nz-form-control>
    18. </nz-form-item>
    19. <nz-form-item>
    20. <nz-form-label><label>PageSizeChanger</label></nz-form-label>
    21. <nz-form-control><nz-switch [(ngModel)]="sizeChanger" name="sizeChanger"></nz-switch></nz-form-control>
    22. </nz-form-item>
    23. <nz-form-item>
    24. <nz-form-label><label>Title</label></nz-form-label>
    25. <nz-form-control><nz-switch [(ngModel)]="title" name="title"></nz-switch></nz-form-control>
    26. </nz-form-item>
    27. <nz-form-item>
    28. <nz-form-label><label>Column Header</label></nz-form-label>
    29. <nz-form-control><nz-switch [(ngModel)]="header" name="header"></nz-switch></nz-form-control>
    30. </nz-form-item>
    31. <nz-form-item>
    32. <nz-form-label><label>Footer</label></nz-form-label>
    33. <nz-form-control><nz-switch [(ngModel)]="footer" name="footer"></nz-switch></nz-form-control>
    34. </nz-form-item>
    35. <nz-form-item>
    36. <nz-form-label><label>Expandable</label></nz-form-label>
    37. <nz-form-control><nz-switch [(ngModel)]="expandable" name="expandable"></nz-switch></nz-form-control>
    38. </nz-form-item>
    39. <nz-form-item>
    40. <nz-form-label><label>Checkbox</label></nz-form-label>
    41. <nz-form-control><nz-switch [(ngModel)]="checkbox" name="checkbox"></nz-switch></nz-form-control>
    42. </nz-form-item>
    43. <nz-form-item>
    44. <nz-form-label><label>Fixed Header</label></nz-form-label>
    45. <nz-form-control><nz-switch [(ngModel)]="fixHeader" name="fixHeader"></nz-switch></nz-form-control>
    46. </nz-form-item>
    47. <nz-form-item>
    48. <nz-form-label><label>No Result</label></nz-form-label>
    49. <nz-form-control
    50. ><nz-switch [(ngModel)]="noResult" (ngModelChange)="noResultChange($event)" name="noResult"></nz-switch
    51. ></nz-form-control>
    52. </nz-form-item>
    53. <nz-form-item>
    54. <nz-form-label><label>Simple Pagination</label></nz-form-label>
    55. <nz-form-control><nz-switch [(ngModel)]="simple" name="simple"></nz-switch></nz-form-control>
    56. </nz-form-item>
    57. <nz-form-item>
    58. <nz-form-label><label>Size</label></nz-form-label>
    59. <nz-form-control>
    60. <nz-radio-group [(ngModel)]="size" name="size">
    61. <label nz-radio-button nzValue="default">Default</label>
    62. <label nz-radio-button nzValue="middle">Middle</label>
    63. <label nz-radio-button nzValue="small">Small</label>
    64. </nz-radio-group>
    65. </nz-form-control>
    66. </nz-form-item>
    67. <nz-form-item>
    68. <nz-form-label><label>Pagination Position</label></nz-form-label>
    69. <nz-form-control>
    70. <nz-radio-group [(ngModel)]="position" name="position">
    71. <label nz-radio-button nzValue="top">Top</label>
    72. <label nz-radio-button nzValue="bottom">Bottom</label>
    73. <label nz-radio-button nzValue="both">Both</label>
    74. </nz-radio-group>
    75. </nz-form-control>
    76. </nz-form-item>
    77. </form>
    78. </div>
    79. <nz-table
    80. #dynamicTable
    81. [nzScroll]="fixHeader ? { y: '240px' } : null"
    82. [nzData]="listOfData"
    83. [nzBordered]="bordered"
    84. [nzSimple]="simple"
    85. [nzLoading]="loading"
    86. [nzPaginationPosition]="position"
    87. [nzShowSizeChanger]="sizeChanger"
    88. [nzFrontPagination]="pagination"
    89. [nzShowPagination]="pagination"
    90. [nzFooter]="footer ? 'Here is Footer' : null"
    91. [nzTitle]="title ? 'Here is Title' : null"
    92. [nzSize]="size"
    93. (nzCurrentPageDataChange)="currentPageDataChange($event)"
    94. >
    95. <thead>
    96. <tr *ngIf="header">
    97. <th nzWidth="50px" nzShowExpand *ngIf="expandable"></th>
    98. <th
    99. nzWidth="62px"
    100. nzShowCheckbox
    101. *ngIf="checkbox"
    102. [(nzChecked)]="allChecked"
    103. [nzIndeterminate]="indeterminate"
    104. (nzCheckedChange)="checkAll($event)"
    105. ></th>
    106. <th nzWidth="150px">Name</th>
    107. <th nzWidth="70px">Age</th>
    108. <th>Address</th>
    109. <th nzWidth="260px">Action</th>
    110. </tr>
    111. </thead>
    112. <tbody>
    113. <ng-template ngFor let-data [ngForOf]="dynamicTable.data">
    114. <tr>
    115. <td nzShowExpand *ngIf="expandable" [(nzExpand)]="data.expand"></td>
    116. <td nzShowCheckbox *ngIf="checkbox" [(nzChecked)]="data.checked" (nzCheckedChange)="refreshStatus()"></td>
    117. <td>{{ data.name }}</td>
    118. <td>{{ data.age }}</td>
    119. <td>{{ data.address }}</td>
    120. <td>
    121. <a href="#">Action 一 {{ data.name }}</a>
    122. <nz-divider nzType="vertical"></nz-divider>
    123. <a href="#">Delete</a>
    124. </td>
    125. </tr>
    126. <tr [nzExpand]="data.expand && expandable">
    127. <td></td>
    128. <td [attr.colspan]="checkbox ? 5 : 4">{{ data.description }}</td>
    129. </tr>
    130. </ng-template>
    131. </tbody>
    132. </nz-table>
    133. `,
    134. styles: [
    135. `
    136. .components-table-demo-control-bar {
    137. margin-bottom: 12px;
    138. }
    139. .nz-form-item {
    140. margin-right: 16px;
    141. margin-bottom: 8px;
    142. }
    143. `
    144. ]
    145. })
    146. export class NzDemoTableDynamicSettingsComponent implements OnInit {
    147. listOfData: any[] = [];
    148. bordered = false;
    149. loading = false;
    150. sizeChanger = false;
    151. pagination = true;
    152. header = true;
    153. title = true;
    154. footer = true;
    155. fixHeader = false;
    156. size = 'small';
    157. expandable = true;
    158. checkbox = true;
    159. allChecked = false;
    160. indeterminate = false;
    161. displayData: any[] = [];
    162. simple = false;
    163. noResult = false;
    164. position = 'bottom';
    165. currentPageDataChange(
    166. $event: Array<{
    167. name: string;
    168. age: number;
    169. address: string;
    170. checked: boolean;
    171. expand: boolean;
    172. description: string;
    173. }>
    174. ): void {
    175. this.displayData = $event;
    176. this.refreshStatus();
    177. }
    178. refreshStatus(): void {
    179. const validData = this.displayData.filter(value => !value.disabled);
    180. const allChecked = validData.length > 0 && validData.every(value => value.checked === true);
    181. const allUnChecked = validData.every(value => !value.checked);
    182. this.allChecked = allChecked;
    183. this.indeterminate = !allChecked && !allUnChecked;
    184. }
    185. checkAll(value: boolean): void {
    186. this.displayData.forEach(data => {
    187. if (!data.disabled) {
    188. data.checked = value;
    189. }
    190. });
    191. this.refreshStatus();
    192. }
    193. ngOnInit(): void {
    194. for (let i = 1; i <= 100; i++) {
    195. this.listOfData.push({
    196. name: 'John Brown',
    197. age: `${i}2`,
    198. address: `New York No. ${i} Lake Park`,
    199. description: `My name is John Brown, I am ${i}2 years old, living in New York No. ${i} Lake Park.`,
    200. checked: false,
    201. expand: false
    202. });
    203. }
    204. }
    205. noResultChange(status: boolean): void {
    206. this.listOfData = [];
    207. if (!status) {
    208. this.ngOnInit();
    209. }
    210. }
    211. }

    API

    单独引入此组件

    想要了解更多关于单独引入组件的内容,可以在快速上手页面进行查看。

    1. import { NzTableModule } from 'ng-zorro-antd';

    nz-tablecomponent

    参数说明类型默认值
    [nzData]数据数组any[]-
    [nzFrontPagination]是否在前端对数据进行分页,如果在服务器分页数据或者需要在前端显示全部数据时传入 falsebooleantrue
    [nzTotal]当前总数据,在服务器渲染时需要传入number-
    [nzPageIndex]当前页码,可双向绑定number-
    [nzPageSize]每页展示多少数据,可双向绑定number-
    [nzShowPagination]是否显示分页器booleantrue
    [nzPaginationPosition]指定分页显示的位置'top'|'bottom'|'both'bottom
    [nzBordered]是否展示外边框和列边框booleanfalse
    [nzWidthConfig]表头分组时指定每列宽度,与 thnzWidth 不可混用string[]-
    [nzSize]正常或迷你类型'middle'|'small'|'default''default'
    [nzLoading]页面是否加载中booleanfalse
    [nzLoadingIndicator]加载指示符TemplateRef<void>-
    [nzLoadingDelay]延迟显示加载效果的时间(防止闪烁)number0
    [nzScroll]横向或纵向支持滚动,也可用于指定滚动区域的宽高度:{ x: "300px", y: "300px" }object-
    [nzTitle]表格标题string|TemplateRef<void>-
    [nzFooter]表格尾部string|TemplateRef<void>-
    [nzNoResult]无数据时显示内容string|TemplateRef<void>-
    [nzPageSizeOptions]页数选择器可选值number[][ 10, 20, 30, 40, 50 ]
    [nzShowQuickJumper]是否可以快速跳转至某页booleanfalse
    [nzShowSizeChanger]是否可以改变 nzPageSizebooleanfalse
    [nzShowTotal]用于显示数据总量和当前数据范围,用法参照 Pagination 组件TemplateRef<{ $implicit: number, range: [ number, number ] }>-
    [nzItemRender]用于自定义页码的结构,用法参照 Pagination 组件TemplateRef<{ $implicit: 'page'|'prev'|'next', page: number }>-
    [nzHideOnSinglePage]只有一页时是否隐藏分页器booleanfalse
    [nzSimple]当添加该属性时,显示为简单分页boolean-
    [nzVirtualScroll]是否启用虚拟滚动模式,与 [nzScroll] 配合使用booleanfalse
    [nzVirtualItemSize]虚拟滚动时每一列的高度,与 cdk itemSize 相同number0
    [nzVirtualMaxBufferPx]缓冲区最大像素高度,与 cdk maxBufferPx 相同number200
    [nzVirtualMinBufferPx]缓冲区最小像素高度,低于该值时将加载新结构,与 cdk minBufferPx 相同number100
    (nzPageIndexChange)当前页码改变时的回调函数EventEmitter<number>-
    (nzPageSizeChange)页数改变时的回调函数EventEmitter<number>-
    (nzCurrentPageDataChange)当前页面展示数据改变的回调函数EventEmitter<any[]>-

    th

    勾选属性

    参数说明类型默认值
    [nzShowCheckbox]是否添加checkboxboolean-
    [nzDisabled]checkbox 是否禁用boolean-
    [nzIndeterminate]checkbox indeterminate 状态boolean-
    [nzChecked]checkbox 是否被选中,可双向绑定boolean-
    (nzCheckedChange)选中的回调EventEmitter<boolean>-

    下拉选择属性

    参数说明类型默认值
    [nzShowRowSelection]是否显示下拉选择boolean-
    [nzSelections]下拉选择的内容 text 及回调函数 onSelectArray<{ text: string, onSelect: any }>-

    排序属性

    参数说明类型默认值
    [nzShowSort]是否显示排序boolean-
    [nzSortKey]排序key,非受控模式使用,与 theadnzSortChange 配合使用string-
    [nzSort]当前排序状态,受控模式使用,可双向绑定'descend'|'ascend'|nullnull
    (nzSortChange)排序状态改变回调,受控模式使用EventEmitter<'descend'|'ascend'|null>-

    过滤属性

    参数说明类型默认值
    [nzShowFilter]是否显示过滤boolean-
    [nzFilters]过滤器内容, 显示数据 text,回调函数传出 value,设置 byDefault 以默认应用过滤规则Array<{ text: string; value: any; byDefault?: boolean }>-
    [nzFilterMultiple]是否为多选过滤器booleantrue
    (nzFilterChange)过滤器内容选择的 value 数据回调EventEmitter<any[]|any>-

    样式属性

    参数说明类型默认值
    [nzWidth]指定该列宽度,表头未分组时可用string-
    [nzLeft]左侧距离,用于固定左侧列string-
    [nzRight]右侧距离,用于固定右侧列string-
    [nzAlign]设置列内容的对齐方式'left'|'right'|'center'-

    其他

    参数说明类型默认值
    [nzExpand]当前列是否包含展开按钮boolean-

    td

    勾选属性

    参数说明类型默认值
    [nzShowCheckbox]是否添加checkboxboolean-
    [nzDisabled]checkbox 是否禁用boolean-
    [nzIndeterminate]checkbox indeterminate 状态boolean-
    [nzChecked]checkbox 是否被选中,可双向绑定boolean-
    (nzCheckedChange)选中的回调EventEmitter<boolean>-

    展开属性

    参数说明类型默认值
    [nzShowExpand]是否显示展开按钮boolean-
    [nzExpand]当前展开按钮状态,可双向绑定boolean-
    (nzExpandChange)当前展开按钮状态改变回调函数EventEmitter<boolean>-

    样式属性

    参数说明类型默认值
    [nzLeft]左侧距离,用于固定左侧列string-
    [nzRight]右侧距离,用于固定右侧列string-
    [nzAlign]设置列内容的对齐方式'left'|'right'|'center'-

    其他

    参数说明类型默认值
    [nzIndentSize]展示树形数据时,每层缩进的宽度,以 px 为单位number-

    thead

    参数说明类型默认值
    [nzSingleSort]是否单列排序模式,非受控排序下使用booleanfalse
    (nzSortChange)排序改变时的回调函数,需要与 th 上的 nzSortKey 同时使用,非受控排序下使用EventEmitter<{ nzSortKey: string, value: 'descend'|'ascend'|null }>-

    tr

    参数说明类型默认值
    [nzExpand]当前列是否展开,与 td 上的 nzExpand 属性配合使用boolean-

    [nz-virtual-scroll]directive

    虚拟滚动时配合 ng-template 使用, 格式为: TemplateRef<{ $implicit: any, index: number }>.

    注意

    按照 Angular 的设计,当需要对 nzData 中的数据进行增删时需要使用以下操作,使用 push 或者 splice 修改 nzData 的数据不会生效

    1. // 增加数据
    2. this.dataSet = [ ...this.dataSet, {
    3. key : `${this.i}`,
    4. name : `Edward King ${this.i}`,
    5. age : '32',
    6. address: `London, Park Lane no. ${this.i}`
    7. }];
    8. // 删除数据
    9. this.dataSet = this.dataSet.filter(d => d.key !== i);