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

    Table表格

    展示行列数据。

    何时使用

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

    单独引入此组件

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

    1. import { NzTableModule } from 'ng-zorro-antd/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

    基本用法

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

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-basic',
      template: `
        <nz-table #basicTable [nzData]="listOfData">
          <thead>
            <tr>
              <th>Name</th>
              <th>Age</th>
              <th>Address</th>
              <th>Action</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of basicTable.data">
              <td>{{ data.name }}</td>
              <td>{{ data.age }}</td>
              <td>{{ data.address }}</td>
              <td>
                <a>Action 一 {{ data.name }}</a>
                <nz-divider nzType="vertical"></nz-divider>
                <a>Delete</a>
              </td>
            </tr>
          </tbody>
        </nz-table>
      `
    })
    export class NzDemoTableBasicComponent {
      listOfData = [
        {
          key: '1',
          name: 'John Brown',
          age: 32,
          address: 'New York No. 1 Lake Park'
        },
        {
          key: '2',
          name: 'Jim Green',
          age: 42,
          address: 'London No. 1 Lake Park'
        },
        {
          key: '3',
          name: 'Joe Black',
          age: 32,
          address: 'Sidney No. 1 Lake Park'
        }
      ];
    }

    Table表格 - 图2

    选择和操作

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

    import { Component, OnInit } from '@angular/core';
    
    export interface Data {
      id: number;
      name: string;
      age: number;
      address: string;
      disabled: boolean;
    }
    
    @Component({
      selector: 'nz-demo-table-row-selection-and-operation',
      template: `
        <div class="operate">
          <button
            nz-button
            [disabled]="numberOfChecked === 0"
            [nzType]="'primary'"
            [nzLoading]="isOperating"
            (click)="operateData()"
          >
            Reload
          </button>
          <span *ngIf="numberOfChecked">Selected {{ numberOfChecked }} items</span>
        </div>
        <nz-table
          #rowSelectionTable
          nzShowPagination
          nzShowSizeChanger
          [nzData]="listOfAllData"
          (nzCurrentPageDataChange)="currentPageDataChange($event)"
        >
          <thead>
            <tr>
              <th
                nzShowCheckbox
                [(nzChecked)]="isAllDisplayDataChecked"
                [nzIndeterminate]="isIndeterminate"
                (nzCheckedChange)="checkAll($event)"
              ></th>
              <th>Name</th>
              <th>Age</th>
              <th>Address</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of rowSelectionTable.data">
              <td
                nzShowCheckbox
                [(nzChecked)]="mapOfCheckedId[data.id]"
                [nzDisabled]="data.disabled"
                (nzCheckedChange)="refreshStatus()"
              ></td>
              <td>{{ data.name }}</td>
              <td>{{ data.age }}</td>
              <td>{{ data.address }}</td>
            </tr>
          </tbody>
        </nz-table>
      `,
      styles: [
        `
          .operate {
            margin-bottom: 16px;
          }
    
          .operate span {
            margin-left: 8px;
          }
        `
      ]
    })
    export class NzDemoTableRowSelectionAndOperationComponent implements OnInit {
      isAllDisplayDataChecked = false;
      isOperating = false;
      isIndeterminate = false;
      listOfDisplayData: Data[] = [];
      listOfAllData: Data[] = [];
      mapOfCheckedId: { [key: string]: boolean } = {};
      numberOfChecked = 0;
    
      currentPageDataChange($event: Data[]): void {
        this.listOfDisplayData = $event;
        this.refreshStatus();
      }
    
      refreshStatus(): void {
        this.isAllDisplayDataChecked = this.listOfDisplayData
          .filter(item => !item.disabled)
          .every(item => this.mapOfCheckedId[item.id]);
        this.isIndeterminate =
          this.listOfDisplayData.filter(item => !item.disabled).some(item => this.mapOfCheckedId[item.id]) &&
          !this.isAllDisplayDataChecked;
        this.numberOfChecked = this.listOfAllData.filter(item => this.mapOfCheckedId[item.id]).length;
      }
    
      checkAll(value: boolean): void {
        this.listOfDisplayData.filter(item => !item.disabled).forEach(item => (this.mapOfCheckedId[item.id] = value));
        this.refreshStatus();
      }
    
      operateData(): void {
        this.isOperating = true;
        setTimeout(() => {
          this.listOfAllData.forEach(item => (this.mapOfCheckedId[item.id] = false));
          this.refreshStatus();
          this.isOperating = false;
        }, 1000);
      }
    
      ngOnInit(): void {
        for (let i = 0; i < 100; i++) {
          this.listOfAllData.push({
            id: i,
            name: `Edward King ${i}`,
            age: 32,
            address: `London, Park Lane no. ${i}`,
            disabled: i % 2 === 0
          });
        }
      }
    }

    Table表格 - 图3

    自定义选择项

    通过 nzShowRowSelectionnzSelections 自定义选择项.

    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-row-selection-custom',
      template: `
        <nz-table
          #rowSelectionTable
          nzShowSizeChanger
          [nzData]="listOfAllData"
          (nzCurrentPageDataChange)="currentPageDataChange($event)"
        >
          <thead>
            <tr>
              <th
                nzShowCheckbox
                nzShowRowSelection
                [nzSelections]="listOfSelection"
                [(nzChecked)]="isAllDisplayDataChecked"
                [nzIndeterminate]="isIndeterminate"
                (nzCheckedChange)="checkAll($event)"
              ></th>
              <th>Name</th>
              <th>Age</th>
              <th>Address</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of rowSelectionTable.data">
              <td nzShowCheckbox [(nzChecked)]="mapOfCheckedId[data.id]" (nzCheckedChange)="refreshStatus()"></td>
              <td>{{ data.name }}</td>
              <td>{{ data.age }}</td>
              <td>{{ data.address }}</td>
            </tr>
          </tbody>
        </nz-table>
      `
    })
    export class NzDemoTableRowSelectionCustomComponent implements OnInit {
      listOfSelection = [
        {
          text: 'Select All Row',
          onSelect: () => {
            this.checkAll(true);
          }
        },
        {
          text: 'Select Odd Row',
          onSelect: () => {
            this.listOfDisplayData.forEach((data, index) => (this.mapOfCheckedId[data.id] = index % 2 !== 0));
            this.refreshStatus();
          }
        },
        {
          text: 'Select Even Row',
          onSelect: () => {
            this.listOfDisplayData.forEach((data, index) => (this.mapOfCheckedId[data.id] = index % 2 === 0));
            this.refreshStatus();
          }
        }
      ];
      isAllDisplayDataChecked = false;
      isIndeterminate = false;
      listOfDisplayData: any[] = [];
      listOfAllData: any[] = [];
      mapOfCheckedId: { [key: string]: boolean } = {};
    
      currentPageDataChange($event: Array<{ id: number; name: string; age: number; address: string }>): void {
        this.listOfDisplayData = $event;
        this.refreshStatus();
      }
    
      refreshStatus(): void {
        this.isAllDisplayDataChecked = this.listOfDisplayData.every(item => this.mapOfCheckedId[item.id]);
        this.isIndeterminate =
          this.listOfDisplayData.some(item => this.mapOfCheckedId[item.id]) && !this.isAllDisplayDataChecked;
      }
    
      checkAll(value: boolean): void {
        this.listOfDisplayData.forEach(item => (this.mapOfCheckedId[item.id] = value));
        this.refreshStatus();
      }
    
      ngOnInit(): void {
        for (let i = 0; i < 100; i++) {
          this.listOfAllData.push({
            id: i,
            name: `Edward King ${i}`,
            age: 32,
            address: `London, Park Lane no. ${i}`
          });
        }
      }
    }

    Table表格 - 图4

    筛选和排序

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

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

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-head',
      template: `
        <nz-table #filterTable [nzData]="listOfDisplayData">
          <thead (nzSortChange)="sort($event)" nzSingleSort>
            <tr>
              <th
                nzShowSort
                nzSortKey="name"
                nzShowFilter
                [nzFilters]="listOfName"
                (nzFilterChange)="filter($event, searchAddress)"
              >
                Name
              </th>
              <th nzShowSort nzSortKey="age">Age</th>
              <th
                nzShowSort
                nzSortKey="address"
                nzShowFilter
                [nzFilterMultiple]="false"
                [nzFilters]="listOfAddress"
                (nzFilterChange)="filter(listOfSearchName, $event)"
              >
                Address
              </th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of filterTable.data">
              <td>{{ data.name }}</td>
              <td>{{ data.age }}</td>
              <td>{{ data.address }}</td>
            </tr>
          </tbody>
        </nz-table>
      `
    })
    export class NzDemoTableHeadComponent {
      sortName: string | null = null;
      sortValue: string | null = null;
      searchAddress: string;
      listOfName = [{ text: 'Joe', value: 'Joe' }, { text: 'Jim', value: 'Jim' }];
      listOfAddress = [{ text: 'London', value: 'London' }, { text: 'Sidney', value: 'Sidney' }];
      listOfSearchName: string[] = [];
      listOfData: Array<{ name: string; age: number; address: string; [key: string]: string | number }> = [
        {
          name: 'John Brown',
          age: 32,
          address: 'New York No. 1 Lake Park'
        },
        {
          name: 'Jim Green',
          age: 42,
          address: 'London No. 1 Lake Park'
        },
        {
          name: 'Joe Black',
          age: 32,
          address: 'Sidney No. 1 Lake Park'
        },
        {
          name: 'Jim Red',
          age: 32,
          address: 'London No. 2 Lake Park'
        }
      ];
      listOfDisplayData: Array<{ name: string; age: number; address: string; [key: string]: string | number }> = [
        ...this.listOfData
      ];
    
      sort(sort: { key: string; value: string }): void {
        this.sortName = sort.key;
        this.sortValue = sort.value;
        this.search();
      }
    
      filter(listOfSearchName: string[], searchAddress: string): void {
        this.listOfSearchName = listOfSearchName;
        this.searchAddress = searchAddress;
        this.search();
      }
    
      search(): void {
        /** filter data **/
        const filterFunc = (item: { name: string; age: number; address: string }) =>
          (this.searchAddress ? item.address.indexOf(this.searchAddress) !== -1 : true) &&
          (this.listOfSearchName.length ? this.listOfSearchName.some(name => item.name.indexOf(name) !== -1) : true);
        const data = this.listOfData.filter(item => filterFunc(item));
        /** sort data **/
        if (this.sortName && this.sortValue) {
          this.listOfDisplayData = data.sort((a, b) =>
            this.sortValue === 'ascend'
              ? a[this.sortName!] > b[this.sortName!]
                ? 1
                : -1
              : b[this.sortName!] > a[this.sortName!]
              ? 1
              : -1
          );
        } else {
          this.listOfDisplayData = data;
        }
      }
    }

    Table表格 - 图5

    默认筛选

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

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-default-filter',
      template: `
        <nz-table #filterTable [nzData]="listOfDisplayData">
          <thead (nzSortChange)="sort($event)" nzSingleSort>
            <tr>
              <th
                nzShowSort
                nzSortKey="name"
                nzShowFilter
                [nzFilters]="listOfName"
                (nzFilterChange)="filter($event, searchAddress)"
              >
                Name
              </th>
              <th nzShowSort nzSortKey="age">Age</th>
              <th
                nzShowSort
                nzSortKey="address"
                nzShowFilter
                [nzFilterMultiple]="false"
                [nzFilters]="listOfAddress"
                (nzFilterChange)="filter(listOfSearchName, $event)"
              >
                Address
              </th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of filterTable.data">
              <td>{{ data.name }}</td>
              <td>{{ data.age }}</td>
              <td>{{ data.address }}</td>
            </tr>
          </tbody>
        </nz-table>
      `
    })
    export class NzDemoTableDefaultFilterComponent {
      listOfName = [{ text: 'Joe', value: 'Joe', byDefault: true }, { text: 'Jim', value: 'Jim' }];
      listOfAddress = [{ text: 'London', value: 'London', byDefault: true }, { text: 'Sidney', value: 'Sidney' }];
      listOfSearchName = ['Joe']; // You need to change it as well!
      sortName: string | null = null;
      sortValue: string | null = null;
      searchAddress = 'London';
      listOfData: Array<{ name: string; age: number; address: string; [key: string]: string | number }> = [
        {
          name: 'John Brown',
          age: 32,
          address: 'New York No. 1 Lake Park'
        },
        {
          name: 'Jim Green',
          age: 42,
          address: 'London No. 1 Lake Park'
        },
        {
          name: 'Joe Black',
          age: 32,
          address: 'Sidney No. 1 Lake Park'
        },
        {
          name: 'Jim Red',
          age: 32,
          address: 'London No. 2 Lake Park'
        }
      ];
      // You need to change it as well!
      listOfDisplayData: Array<{ name: string; age: number; address: string; [key: string]: string | number }> = [];
    
      sort(sort: { key: string; value: string }): void {
        this.sortName = sort.key;
        this.sortValue = sort.value;
        this.search();
      }
    
      filter(listOfSearchName: string[], searchAddress: string): void {
        console.log(listOfSearchName, searchAddress);
        this.listOfSearchName = listOfSearchName;
        this.searchAddress = searchAddress;
        this.search();
      }
    
      search(): void {
        /** filter data **/
        const filterFunc = (item: { name: string; age: number; address: string }) =>
          (this.searchAddress ? item.address.indexOf(this.searchAddress) !== -1 : true) &&
          (this.listOfSearchName.length ? this.listOfSearchName.some(name => item.name.indexOf(name) !== -1) : true);
        const data = this.listOfData.filter(item => filterFunc(item));
        /** sort data **/
        if (this.sortName && this.sortValue) {
          this.listOfDisplayData = data.sort((a, b) =>
            this.sortValue === 'ascend'
              ? a[this.sortName!] > b[this.sortName!]
                ? 1
                : -1
              : b[this.sortName!] > a[this.sortName!]
              ? 1
              : -1
          );
        } else {
          this.listOfDisplayData = data;
        }
      }
    }

    Table表格 - 图6

    可控的筛选和排序

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

    1. th 中定义了 nzSort 属性即视为受控模式。
    2. 通过手动指定 nzSort 来指定当前列的排序状态
    3. 通过 thnzSortChange 事件来获取当前列排序状态的改变
    4. 不可与 thead 中的 nzSortChangenzSingleSort 同时使用
    import { Component } from '@angular/core';
    
    interface Data {
      name: string;
      age: number;
      address: string;
    
      [key: string]: any;
    }
    
    @Component({
      selector: 'nz-demo-table-reset-filter',
      template: `
        <div class="table-operations">
          <button nz-button (click)="sort('age', 'descend')">Sort age</button>
          <button nz-button (click)="resetFilters()">Clear filters</button>
          <button nz-button (click)="resetSortAndFilters()">Clear filters and sorters</button>
        </div>
        <nz-table #filterTable [nzData]="listOfDisplayData">
          <thead>
            <tr>
              <th
                nzShowSort
                nzShowFilter
                [(nzSort)]="mapOfSort.name"
                (nzSortChange)="sort('name', $event)"
                [nzFilters]="listOfFilterName"
                (nzFilterChange)="search($event, listOfSearchAddress)"
              >
                Name
              </th>
              <th nzShowSort [(nzSort)]="mapOfSort.age" (nzSortChange)="sort('age', $event)">Age</th>
              <th
                nzShowSort
                nzShowFilter
                [(nzSort)]="mapOfSort.address"
                (nzSortChange)="sort('address', $event)"
                [nzFilters]="listOfFilterAddress"
                (nzFilterChange)="search(listOfSearchName, $event)"
              >
                Address
              </th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of filterTable.data">
              <td>{{ data.name }}</td>
              <td>{{ data.age }}</td>
              <td>{{ data.address }}</td>
            </tr>
          </tbody>
        </nz-table>
      `,
      styles: [
        `
          .table-operations {
            margin-bottom: 16px;
          }
    
          .table-operations > button {
            margin-right: 8px;
          }
        `
      ]
    })
    export class NzDemoTableResetFilterComponent {
      listOfSearchName: string[] = [];
      listOfSearchAddress: string[] = [];
      listOfFilterName = [{ text: 'Joe', value: 'Joe' }, { text: 'Jim', value: 'Jim' }];
      listOfFilterAddress = [{ text: 'London', value: 'London' }, { text: 'Sidney', value: 'Sidney' }];
      listOfData: Data[] = [
        {
          name: 'John Brown',
          age: 32,
          address: 'New York No. 1 Lake Park'
        },
        {
          name: 'Jim Green',
          age: 42,
          address: 'London No. 1 Lake Park'
        },
        {
          name: 'Joe Black',
          age: 32,
          address: 'Sidney No. 1 Lake Park'
        },
        {
          name: 'Jim Red',
          age: 32,
          address: 'London No. 2 Lake Park'
        }
      ];
      listOfDisplayData = [...this.listOfData];
      mapOfSort: { [key: string]: any } = {
        name: null,
        age: null,
        address: null
      };
      sortName: string | null = null;
      sortValue: string | null = null;
    
      sort(sortName: string, value: string): void {
        this.sortName = sortName;
        this.sortValue = value;
        for (const key in this.mapOfSort) {
          this.mapOfSort[key] = key === sortName ? value : null;
        }
        this.search(this.listOfSearchName, this.listOfSearchAddress);
      }
    
      search(listOfSearchName: string[], listOfSearchAddress: string[]): void {
        this.listOfSearchName = listOfSearchName;
        this.listOfSearchAddress = listOfSearchAddress;
        const filterFunc = (item: Data) =>
          (this.listOfSearchAddress.length
            ? this.listOfSearchAddress.some(address => item.address.indexOf(address) !== -1)
            : true) &&
          (this.listOfSearchName.length ? this.listOfSearchName.some(name => item.name.indexOf(name) !== -1) : true);
        const listOfData = this.listOfData.filter((item: Data) => filterFunc(item));
        if (this.sortName && this.sortValue) {
          this.listOfDisplayData = listOfData.sort((a, b) =>
            this.sortValue === 'ascend'
              ? a[this.sortName!] > b[this.sortName!]
                ? 1
                : -1
              : b[this.sortName!] > a[this.sortName!]
              ? 1
              : -1
          );
        } else {
          this.listOfDisplayData = listOfData;
        }
      }
    
      resetFilters(): void {
        this.listOfFilterName = [{ text: 'Joe', value: 'Joe' }, { text: 'Jim', value: 'Jim' }];
        this.listOfFilterAddress = [{ text: 'London', value: 'London' }, { text: 'Sidney', value: 'Sidney' }];
        this.listOfSearchName = [];
        this.listOfSearchAddress = [];
        this.search(this.listOfSearchName, this.listOfSearchAddress);
      }
    
      resetSortAndFilters(): void {
        this.sortName = null;
        this.sortValue = null;
        this.mapOfSort = {
          name: null,
          age: null,
          address: null
        };
        this.resetFilters();
        this.search(this.listOfSearchName, this.listOfSearchAddress);
      }
    }

    Table表格 - 图7

    自定义筛选菜单

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

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-custom-filter-panel',
      template: `
        <nz-table #nzTable [nzData]="listOfDisplayData">
          <thead>
            <tr>
              <th nzCustomFilter>
                Name
                <i
                  class="ant-table-filter-icon"
                  nz-icon
                  nz-dropdown
                  #dropdown="nzDropdown"
                  nzType="search"
                  [nzDropdownMenu]="menu"
                  [class.ant-table-filter-open]="dropdown.nzVisible"
                  nzTrigger="click"
                  nzPlacement="bottomRight"
                  [nzClickHide]="false"
                  nzTableFilter
                ></i>
              </th>
              <th>Age</th>
              <th nzShowFilter [nzFilters]="listOfFilterAddress" (nzFilterChange)="filterAddressChange($event)">Address</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of nzTable.data">
              <td>{{ data.name }}</td>
              <td>{{ data.age }}</td>
              <td>{{ data.address }}</td>
            </tr>
          </tbody>
        </nz-table>
        <nz-dropdown-menu #menu="nzDropdownMenu">
          <div class="search-box">
            <input type="text" nz-input placeholder="Search name" [(ngModel)]="searchValue" />
            <button nz-button nzSize="small" nzType="primary" (click)="search()" class="search-button">
              Search
            </button>
            <button nz-button nzSize="small" (click)="reset()">Reset</button>
          </div>
        </nz-dropdown-menu>
      `,
      styles: [
        `
          .search-box {
            padding: 8px;
          }
    
          .search-box input {
            width: 188px;
            margin-bottom: 8px;
            display: block;
          }
    
          .search-box button {
            width: 90px;
          }
    
          .search-button {
            margin-right: 8px;
          }
        `
      ]
    })
    export class NzDemoTableCustomFilterPanelComponent {
      searchValue = '';
      sortName: string | null = null;
      sortValue: string | null = null;
      listOfFilterAddress = [{ text: 'London', value: 'London' }, { text: 'Sidney', value: 'Sidney' }];
      listOfSearchAddress: string[] = [];
      listOfData: Array<{ name: string; age: number; address: string; [key: string]: string | number }> = [
        {
          name: 'John Brown',
          age: 32,
          address: 'New York No. 1 Lake Park'
        },
        {
          name: 'Jim Green',
          age: 42,
          address: 'London No. 1 Lake Park'
        },
        {
          name: 'Joe Black',
          age: 32,
          address: 'Sidney No. 1 Lake Park'
        },
        {
          name: 'Jim Red',
          age: 32,
          address: 'London No. 2 Lake Park'
        }
      ];
      listOfDisplayData = [...this.listOfData];
    
      reset(): void {
        this.searchValue = '';
        this.search();
      }
    
      sort(sortName: string, value: string): void {
        this.sortName = sortName;
        this.sortValue = value;
        this.search();
      }
    
      filterAddressChange(value: string[]): void {
        this.listOfSearchAddress = value;
        this.search();
      }
    
      search(): void {
        const filterFunc = (item: { name: string; age: number; address: string }) => {
          return (
            (this.listOfSearchAddress.length
              ? this.listOfSearchAddress.some(address => item.address.indexOf(address) !== -1)
              : true) && item.name.indexOf(this.searchValue) !== -1
          );
        };
        const data = this.listOfData.filter((item: { name: string; age: number; address: string }) => filterFunc(item));
        this.listOfDisplayData = data.sort((a, b) =>
          this.sortValue === 'ascend'
            ? a[this.sortName!] > b[this.sortName!]
              ? 1
              : -1
            : b[this.sortName!] > a[this.sortName!]
            ? 1
            : -1
        );
      }
    }

    Table表格 - 图8

    远程加载数据

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

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

    import { HttpClient, HttpParams } from '@angular/common/http';
    import { Component, Injectable, OnInit } from '@angular/core';
    import { Observable } from 'rxjs';
    
    @Injectable()
    export class RandomUserService {
      randomUserUrl = 'https://api.randomuser.me/';
    
      getUsers(
        pageIndex: number = 1,
        pageSize: number = 10,
        sortField: string,
        sortOrder: string,
        genders: string[]
      ): Observable<{}> {
        let params = new HttpParams()
          .append('page', `${pageIndex}`)
          .append('results', `${pageSize}`)
          .append('sortField', sortField)
          .append('sortOrder', sortOrder);
        genders.forEach(gender => {
          params = params.append('gender', gender);
        });
        return this.http.get(`${this.randomUserUrl}`, {
          params
        });
      }
    
      constructor(private http: HttpClient) {}
    }
    
    @Component({
      selector: 'nz-demo-table-ajax',
      providers: [RandomUserService],
      template: `
        <nz-table
          #ajaxTable
          nzShowSizeChanger
          [nzFrontPagination]="false"
          [nzData]="listOfData"
          [nzLoading]="loading"
          [nzTotal]="total"
          [(nzPageIndex)]="pageIndex"
          [(nzPageSize)]="pageSize"
          (nzPageIndexChange)="searchData()"
          (nzPageSizeChange)="searchData(true)"
        >
          <thead (nzSortChange)="sort($event)" nzSingleSort>
            <tr>
              <th nzShowSort nzSortKey="name">Name</th>
              <th nzShowFilter [nzFilters]="filterGender" (nzFilterChange)="updateFilter($event)">Gender</th>
              <th nzShowSort nzSortKey="email"><span>Email</span></th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of ajaxTable.data">
              <td>{{ data.name.first }} {{ data.name.last }}</td>
              <td>{{ data.gender }}</td>
              <td>{{ data.email }}</td>
            </tr>
          </tbody>
        </nz-table>
      `
    })
    export class NzDemoTableAjaxComponent implements OnInit {
      pageIndex = 1;
      pageSize = 10;
      total = 1;
      listOfData = [];
      loading = true;
      sortValue: string | null = null;
      sortKey: string | null = null;
      filterGender = [{ text: 'male', value: 'male' }, { text: 'female', value: 'female' }];
      searchGenderList: string[] = [];
    
      sort(sort: { key: string; value: string }): void {
        this.sortKey = sort.key;
        this.sortValue = sort.value;
        this.searchData();
      }
    
      constructor(private randomUserService: RandomUserService) {}
    
      searchData(reset: boolean = false): void {
        if (reset) {
          this.pageIndex = 1;
        }
        this.loading = true;
        this.randomUserService
          .getUsers(this.pageIndex, this.pageSize, this.sortKey!, this.sortValue!, this.searchGenderList)
          .subscribe((data: any) => {
            this.loading = false;
            this.total = 200;
            this.listOfData = data.results;
          });
      }
    
      updateFilter(value: string[]): void {
        this.searchGenderList = value;
        this.searchData(true);
      }
    
      ngOnInit(): void {
        this.searchData();
      }
    }

    Table表格 - 图9

    紧凑型

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

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-size',
      template: `
        <h4>Middle size table</h4>
        <nz-table #middleTable nzSize="middle" [nzData]="data">
          <thead>
            <tr>
              <th>Name</th>
              <th>Age</th>
              <th>Address</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of middleTable.data">
              <td>{{ data.name }}</td>
              <td>{{ data.age }}</td>
              <td>{{ data.address }}</td>
            </tr>
          </tbody>
        </nz-table>
        <h4>Small size table</h4>
        <nz-table #smallTable nzSize="small" [nzData]="data">
          <thead>
            <tr>
              <th>Name</th>
              <th>Age</th>
              <th>Address</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of smallTable.data">
              <td>{{ data.name }}</td>
              <td>{{ data.age }}</td>
              <td>{{ data.address }}</td>
            </tr>
          </tbody>
        </nz-table>
      `,
      styles: [
        `
          h4 {
            margin-bottom: 16px;
          }
        `
      ]
    })
    export class NzDemoTableSizeComponent {
      data = [
        {
          key: '1',
          name: 'John Brown',
          age: 32,
          address: 'New York No. 1 Lake Park'
        },
        {
          key: '2',
          name: 'Jim Green',
          age: 42,
          address: 'London No. 1 Lake Park'
        },
        {
          key: '3',
          name: 'Joe Black',
          age: 32,
          address: 'Sidney No. 1 Lake Park'
        }
      ];
    }

    Table表格 - 图10

    带边框

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

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-bordered',
      template: `
        <nz-table #borderedTable nzBordered nzFooter="Footer" nzTitle="Header" [nzData]="dataSet">
          <thead>
            <tr>
              <th>Name</th>
              <th>Age</th>
              <th>Address</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of borderedTable.data">
              <td>{{ data.name }}</td>
              <td>{{ data.age }}</td>
              <td>{{ data.address }}</td>
            </tr>
          </tbody>
        </nz-table>
      `
    })
    export class NzDemoTableBorderedComponent {
      dataSet = [
        {
          key: '1',
          name: 'John Brown',
          age: 32,
          address: 'New York No. 1 Lake Park'
        },
        {
          key: '2',
          name: 'Jim Green',
          age: 42,
          address: 'London No. 1 Lake Park'
        },
        {
          key: '3',
          name: 'Joe Black',
          age: 32,
          address: 'Sidney No. 1 Lake Park'
        }
      ];
    }

    Table表格 - 图11

    可展开

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

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-expand',
      template: `
        <nz-table #nzTable [nzData]="listOfData">
          <thead>
            <tr>
              <th nzShowExpand></th>
              <th>Name</th>
              <th>Age</th>
              <th>Address</th>
            </tr>
          </thead>
          <tbody>
            <ng-template ngFor let-data [ngForOf]="nzTable.data">
              <tr>
                <td nzShowExpand [(nzExpand)]="mapOfExpandData[data.id]"></td>
                <td>{{ data.name }}</td>
                <td>{{ data.age }}</td>
                <td>{{ data.address }}</td>
              </tr>
              <tr [nzExpand]="mapOfExpandData[data.id]">
                <td></td>
                <td colspan="3">{{ data.description }}</td>
              </tr>
            </ng-template>
          </tbody>
        </nz-table>
      `
    })
    export class NzDemoTableExpandComponent {
      mapOfExpandData: { [key: string]: boolean } = {};
      listOfData = [
        {
          id: 1,
          name: 'John Brown',
          age: 32,
          expand: false,
          address: 'New York No. 1 Lake Park',
          description: 'My name is John Brown, I am 32 years old, living in New York No. 1 Lake Park.'
        },
        {
          id: 2,
          name: 'Jim Green',
          age: 42,
          expand: false,
          address: 'London No. 1 Lake Park',
          description: 'My name is Jim Green, I am 42 years old, living in London No. 1 Lake Park.'
        },
        {
          id: 3,
          name: 'Joe Black',
          age: 32,
          expand: false,
          address: 'Sidney No. 1 Lake Park',
          description: 'My name is Joe Black, I am 32 years old, living in Sidney No. 1 Lake Park.'
        }
      ];
    }

    Table表格 - 图12

    表格行/列合并

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

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-colspan-rowspan',
      template: `
        <nz-table #colSpanTable [nzData]="listOfData" nzBordered>
          <thead>
            <tr>
              <th>Name</th>
              <th>Age</th>
              <th colspan="2">Home phone</th>
              <th>Address</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of colSpanTable.data; index as i">
              <td>{{ data.name }}</td>
              <td [attr.colspan]="i === 4 ? 5 : 1">{{ data.age }}</td>
              <td [attr.rowspan]="i === 2 ? 2 : 1" *ngIf="i !== 3 && i !== 4">{{ data.tel }}</td>
              <td *ngIf="i !== 4">{{ data.phone }}</td>
              <td *ngIf="i !== 4">{{ data.address }}</td>
            </tr>
          </tbody>
        </nz-table>
      `
    })
    export class NzDemoTableColspanRowspanComponent {
      listOfData = [
        {
          key: '1',
          name: 'John Brown',
          age: 32,
          tel: '0571-22098909',
          phone: 18889898989,
          address: 'New York No. 1 Lake Park'
        },
        {
          key: '2',
          name: 'Jim Green',
          tel: '0571-22098333',
          phone: 18889898888,
          age: 42,
          address: 'London No. 1 Lake Park'
        },
        {
          key: '3',
          name: 'Joe Black',
          age: 32,
          tel: '0575-22098909',
          phone: 18900010002,
          address: 'Sidney No. 1 Lake Park'
        },
        {
          key: '4',
          name: 'Jim Red',
          age: 18,
          tel: '0575-22098909',
          phone: 18900010002,
          address: 'London No. 2 Lake Park'
        },
        {
          key: '5',
          name: 'Jake White',
          age: 18,
          tel: '0575-22098909',
          phone: 18900010002,
          address: 'Dublin No. 2 Lake Park'
        }
      ];
    }

    Table表格 - 图13

    树形数据展示

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

    import { Component, OnInit } from '@angular/core';
    
    export interface TreeNodeInterface {
      key: number;
      name: string;
      age: number;
      level: number;
      expand: boolean;
      address: string;
      children?: TreeNodeInterface[];
    }
    
    @Component({
      selector: 'nz-demo-table-expand-children',
      template: `
        <nz-table #expandTable [nzData]="listOfMapData">
          <thead>
            <tr>
              <th nzWidth="40%">Name</th>
              <th nzWidth="30%">Age</th>
              <th>Address</th>
            </tr>
          </thead>
          <tbody>
            <ng-container *ngFor="let data of expandTable.data">
              <ng-container *ngFor="let item of mapOfExpandedData[data.key]">
                <tr *ngIf="(item.parent && item.parent.expand) || !item.parent">
                  <td
                    [nzIndentSize]="item.level * 20"
                    [nzShowExpand]="!!item.children"
                    [(nzExpand)]="item.expand"
                    (nzExpandChange)="collapse(mapOfExpandedData[data.key], item, $event)"
                  >
                    {{ item.name }}
                  </td>
                  <td>{{ item.age }}</td>
                  <td>{{ item.address }}</td>
                </tr>
              </ng-container>
            </ng-container>
          </tbody>
        </nz-table>
      `
    })
    export class NzDemoTableExpandChildrenComponent implements OnInit {
      listOfMapData = [
        {
          key: 1,
          name: 'John Brown sr.',
          age: 60,
          address: 'New York No. 1 Lake Park',
          children: [
            {
              key: 11,
              name: 'John Brown',
              age: 42,
              address: 'New York No. 2 Lake Park'
            },
            {
              key: 12,
              name: 'John Brown jr.',
              age: 30,
              address: 'New York No. 3 Lake Park',
              children: [
                {
                  key: 121,
                  name: 'Jimmy Brown',
                  age: 16,
                  address: 'New York No. 3 Lake Park'
                }
              ]
            },
            {
              key: 13,
              name: 'Jim Green sr.',
              age: 72,
              address: 'London No. 1 Lake Park',
              children: [
                {
                  key: 131,
                  name: 'Jim Green',
                  age: 42,
                  address: 'London No. 2 Lake Park',
                  children: [
                    {
                      key: 1311,
                      name: 'Jim Green jr.',
                      age: 25,
                      address: 'London No. 3 Lake Park'
                    },
                    {
                      key: 1312,
                      name: 'Jimmy Green sr.',
                      age: 18,
                      address: 'London No. 4 Lake Park'
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          key: 2,
          name: 'Joe Black',
          age: 32,
          address: 'Sidney No. 1 Lake Park'
        }
      ];
      mapOfExpandedData: { [key: string]: TreeNodeInterface[] } = {};
    
      collapse(array: TreeNodeInterface[], data: TreeNodeInterface, $event: boolean): void {
        if ($event === false) {
          if (data.children) {
            data.children.forEach(d => {
              const target = array.find(a => a.key === d.key)!;
              target.expand = false;
              this.collapse(array, target, false);
            });
          } else {
            return;
          }
        }
      }
    
      convertTreeToList(root: object): TreeNodeInterface[] {
        const stack: any[] = [];
        const array: any[] = [];
        const hashMap = {};
        stack.push({ ...root, level: 0, expand: false });
    
        while (stack.length !== 0) {
          const node = stack.pop();
          this.visitNode(node, hashMap, array);
          if (node.children) {
            for (let i = node.children.length - 1; i >= 0; i--) {
              stack.push({ ...node.children[i], level: node.level + 1, expand: false, parent: node });
            }
          }
        }
    
        return array;
      }
    
      visitNode(node: TreeNodeInterface, hashMap: { [key: string]: any }, array: TreeNodeInterface[]): void {
        if (!hashMap[node.key]) {
          hashMap[node.key] = true;
          array.push(node);
        }
      }
    
      ngOnInit(): void {
        this.listOfMapData.forEach(item => {
          this.mapOfExpandedData[item.key] = this.convertTreeToList(item);
        });
      }
    }

    Table表格 - 图14

    固定表头

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

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

    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-fixed-header',
      template: `
        <nz-table #headerTable [nzData]="listOfData" [nzPageSize]="50" [nzScroll]="{ y: '240px' }">
          <thead>
            <tr>
              <th nzWidth="150px">Name</th>
              <th nzWidth="150px">Age</th>
              <th>Address</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of headerTable.data">
              <td>{{ data.name }}</td>
              <td>{{ data.age }}</td>
              <td>{{ data.address }}</td>
            </tr>
          </tbody>
        </nz-table>
      `
    })
    export class NzDemoTableFixedHeaderComponent implements OnInit {
      listOfData: any[] = [];
    
      ngOnInit(): void {
        for (let i = 0; i < 100; i++) {
          this.listOfData.push({
            name: `Edward King ${i}`,
            age: 32,
            address: `London, Park Lane no. ${i}`
          });
        }
      }
    }

    Table表格 - 图15

    固定列

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

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

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

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

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-fixed-columns',
      template: `
        <nz-table #columnTable [nzData]="listOfData" [nzScroll]="{ x: '1100px' }">
          <thead>
            <tr>
              <th nzWidth="100px" nzLeft="0px">Full Name</th>
              <th nzWidth="100px" nzLeft="100px">Age</th>
              <th nzWidth="100px">Column 1</th>
              <th nzWidth="100px">Column 2</th>
              <th nzWidth="100px">Column 3</th>
              <th nzWidth="100px">Column 4</th>
              <th nzWidth="100px">Column 5</th>
              <th nzWidth="100px">Column 6</th>
              <th nzWidth="100px">Column 7</th>
              <th nzRight="100px" nzWidth="100px">Column 8</th>
              <th nzWidth="100px" nzRight="0px">Action</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of columnTable.data">
              <td nzLeft="0px">{{ data.name }}</td>
              <td nzLeft="100px">{{ data.age }}</td>
              <td>{{ data.address }}</td>
              <td>{{ data.address }}</td>
              <td>{{ data.address }}</td>
              <td>{{ data.address }}</td>
              <td>{{ data.address }}</td>
              <td>{{ data.address }}</td>
              <td>{{ data.address }}</td>
              <td nzRight="100px">{{ data.address }}</td>
              <td nzRight="0px">
                <a>action</a>
              </td>
            </tr>
          </tbody>
        </nz-table>
      `
    })
    export class NzDemoTableFixedColumnsComponent {
      listOfData = [
        {
          key: '1',
          name: 'John Brown',
          age: 32,
          address: 'New York'
        },
        {
          key: '2',
          name: 'Jim Green',
          age: 40,
          address: 'London'
        }
      ];
    }

    Table表格 - 图16

    固定头和列

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

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

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

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

    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-fixed-columns-header',
      template: `
        <nz-table #fixedTable [nzData]="listOfData" [nzScroll]="{ x: '1150px', y: '240px' }">
          <thead>
            <tr>
              <th nzWidth="150px" nzLeft="0px">Full Name</th>
              <th nzWidth="100px" nzLeft="150px">Age</th>
              <th nzWidth="100px">Column 1</th>
              <th nzWidth="100px">Column 2</th>
              <th nzWidth="100px">Column 3</th>
              <th nzWidth="100px">Column 4</th>
              <th nzWidth="100px">Column 5</th>
              <th nzWidth="100px">Column 6</th>
              <th nzWidth="100px">Column 7</th>
              <th nzWidth="100px">Column 8</th>
              <th nzWidth="100px" nzRight="0px">Action</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of fixedTable.data">
              <td nzLeft="0px">{{ data.name }}</td>
              <td nzLeft="150px">{{ data.age }}</td>
              <td>{{ data.address }}</td>
              <td>{{ data.address }}</td>
              <td>{{ data.address }}</td>
              <td>{{ data.address }}</td>
              <td>{{ data.address }}</td>
              <td>{{ data.address }}</td>
              <td>{{ data.address }}</td>
              <td>{{ data.address }}</td>
              <td nzRight="0px">
                <a>action</a>
              </td>
            </tr>
          </tbody>
        </nz-table>
      `
    })
    export class NzDemoTableFixedColumnsHeaderComponent implements OnInit {
      listOfData: any[] = [];
    
      ngOnInit(): void {
        for (let i = 0; i < 100; i++) {
          this.listOfData.push({
            name: `Edward King ${i}`,
            age: 32,
            address: `London`
          });
        }
      }
    }

    Table表格 - 图17

    表头分组

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

    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-grouping-columns',
      template: `
        <nz-table
          #groupingTable
          [nzData]="listOfDisplayData"
          nzBordered
          nzSize="middle"
          [nzWidthConfig]="widthConfig"
          [nzScroll]="scrollConfig"
        >
          <thead>
            <tr>
              <th rowspan="4" nzLeft="0px" nzShowFilter [nzFilters]="filterName" (nzFilterChange)="search($event)">Name</th>
              <th colspan="4">Other</th>
              <th colspan="2">Company</th>
              <th rowspan="4" nzRight="0px">Gender</th>
            </tr>
            <tr>
              <th rowspan="3" nzShowSort [(nzSort)]="sortValue" (nzSortChange)="search(searchName)">Age</th>
              <th colspan="3">Address</th>
              <th rowspan="3">Company Address</th>
              <th rowspan="3">Company Name</th>
            </tr>
            <tr>
              <th rowspan="2">Street</th>
              <th colspan="2">Block</th>
            </tr>
            <tr>
              <th>Building</th>
              <th>Door No.</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of groupingTable.data">
              <td nzLeft="0px">{{ data.name }}</td>
              <td>{{ data.age }}</td>
              <td>{{ data.street }}</td>
              <td>{{ data.building }}</td>
              <td>{{ data.number }}</td>
              <td>{{ data.companyAddress }}</td>
              <td>{{ data.companyName }}</td>
              <td nzRight="0px">{{ data.gender }}</td>
            </tr>
          </tbody>
        </nz-table>
      `
    })
    export class NzDemoTableGroupingColumnsComponent implements OnInit {
      widthConfig = ['100px', '200px', '200px', '100px', '100px', '200px', '200px', '100px'];
      scrollConfig = { x: '1200px', y: '240px' };
      listOfDisplayData: any[] = [];
      listOfData: any[] = [];
      sortValue: string | null = null;
      filterName = [{ text: 'Joe', value: 'Joe' }, { text: 'John', value: 'John' }];
      searchName: string[] = [];
    
      search(searchName: string[]): void {
        this.searchName = searchName;
        const filterFunc = (item: any) => {
          return this.searchName.length ? this.searchName.some(name => item.name.indexOf(name) !== -1) : true;
        };
        const listOfData = this.listOfData.filter(item => filterFunc(item));
        this.listOfDisplayData = listOfData.sort((a, b) =>
          this.sortValue === 'ascend' ? (a.age > b.age ? 1 : -1) : b.age > a.age ? 1 : -1
        );
      }
    
      ngOnInit(): void {
        for (let i = 0; i < 100; i++) {
          this.listOfData.push({
            name: 'John Brown',
            age: i + 1,
            street: 'Lake Park',
            building: 'C',
            number: 2035,
            companyAddress: 'Lake Street 42',
            companyName: 'SoftLake Co',
            gender: 'M'
          });
        }
        this.listOfDisplayData = [...this.listOfData];
      }
    }

    Table表格 - 图18

    可编辑单元格

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

    import { Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core';
    import { NzInputDirective } from 'ng-zorro-antd/input';
    
    @Component({
      selector: 'nz-demo-table-edit-cell',
      template: `
        <button nz-button (click)="addRow()" nzType="primary">Add</button>
        <nz-table #editRowTable nzBordered [nzData]="listOfData">
          <thead>
            <tr>
              <th nzWidth="30%">Name</th>
              <th>Age</th>
              <th>Address</th>
              <th>Action</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of editRowTable.data" class="editable-row">
              <td>
                <div class="editable-cell" *ngIf="editId !== data.id; else editTpl">
                  <div class="editable-cell-value-wrap" (click)="startEdit(data.id, $event)">
                    {{ data.name }}
                  </div>
                </div>
                <ng-template #editTpl>
                  <input type="text" nz-input [(ngModel)]="data.name" />
                </ng-template>
              </td>
              <td>{{ data.age }}</td>
              <td>{{ data.address }}</td>
              <td>
                <a nz-popconfirm nzTitle="Sure to delete?" (nzOnConfirm)="deleteRow(data.id)">Delete</a>
              </td>
            </tr>
          </tbody>
        </nz-table>
      `,
      styles: [
        `
          button {
            margin-bottom: 16px;
          }
    
          .editable-cell {
            position: relative;
          }
    
          .editable-cell-value-wrap {
            padding: 5px 12px;
            cursor: pointer;
          }
    
          .editable-row:hover .editable-cell-value-wrap {
            border: 1px solid #d9d9d9;
            border-radius: 4px;
            padding: 4px 11px;
          }
        `
      ]
    })
    export class NzDemoTableEditCellComponent implements OnInit {
      i = 0;
      editId: string | null;
      listOfData: any[] = [];
      @ViewChild(NzInputDirective, { static: false, read: ElementRef }) inputElement: ElementRef;
    
      @HostListener('window:click', ['$event'])
      handleClick(e: MouseEvent): void {
        if (this.editId && this.inputElement && this.inputElement.nativeElement !== e.target) {
          this.editId = null;
        }
      }
    
      addRow(): void {
        this.listOfData = [
          ...this.listOfData,
          {
            id: `${this.i}`,
            name: `Edward King ${this.i}`,
            age: '32',
            address: `London, Park Lane no. ${this.i}`
          }
        ];
        this.i++;
      }
    
      deleteRow(id: string): void {
        this.listOfData = this.listOfData.filter(d => d.id !== id);
      }
    
      startEdit(id: string, event: MouseEvent): void {
        event.preventDefault();
        event.stopPropagation();
        this.editId = id;
      }
    
      ngOnInit(): void {
        this.addRow();
        this.addRow();
      }
    }

    Table表格 - 图19

    可编辑行

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

    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-edit-row',
      template: `
        <nz-table #editRowTable nzBordered [nzData]="listOfData">
          <thead>
            <tr>
              <th nzWidth="25%">Name</th>
              <th nzWidth="15%">Age</th>
              <th nzWidth="40%">Address</th>
              <th>Action</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of editRowTable.data">
              <td>
                <ng-container *ngIf="!editCache[data.id].edit; else nameInputTpl">
                  {{ data.name }}
                </ng-container>
                <ng-template #nameInputTpl>
                  <input type="text" nz-input [(ngModel)]="editCache[data.id].data.name" />
                </ng-template>
              </td>
              <td>
                <ng-container *ngIf="!editCache[data.id].edit; else ageInputTpl">
                  {{ data.age }}
                </ng-container>
                <ng-template #ageInputTpl>
                  <input type="text" nz-input [(ngModel)]="editCache[data.id].data.age" />
                </ng-template>
              </td>
              <td>
                <ng-container *ngIf="!editCache[data.id].edit; else addressInputTpl">
                  {{ data.address }}
                </ng-container>
                <ng-template #addressInputTpl>
                  <input type="text" nz-input [(ngModel)]="editCache[data.id].data.address" />
                </ng-template>
              </td>
              <td>
                <div class="editable-row-operations">
                  <ng-container *ngIf="!editCache[data.id].edit; else saveTpl">
                    <a (click)="startEdit(data.id)">Edit</a>
                  </ng-container>
                  <ng-template #saveTpl>
                    <a (click)="saveEdit(data.id)">Save</a>
                    <a nz-popconfirm nzTitle="Sure to cancel?" (nzOnConfirm)="cancelEdit(data.id)">Cancel</a>
                  </ng-template>
                </div>
              </td>
            </tr>
          </tbody>
        </nz-table>
      `,
      styles: [
        `
          .editable-row-operations a {
            margin-right: 8px;
          }
        `
      ]
    })
    export class NzDemoTableEditRowComponent implements OnInit {
      editCache: { [key: string]: any } = {};
      listOfData: any[] = [];
    
      startEdit(id: string): void {
        this.editCache[id].edit = true;
      }
    
      cancelEdit(id: string): void {
        const index = this.listOfData.findIndex(item => item.id === id);
        this.editCache[id] = {
          data: { ...this.listOfData[index] },
          edit: false
        };
      }
    
      saveEdit(id: string): void {
        const index = this.listOfData.findIndex(item => item.id === id);
        Object.assign(this.listOfData[index], this.editCache[id].data);
        this.editCache[id].edit = false;
      }
    
      updateEditCache(): void {
        this.listOfData.forEach(item => {
          this.editCache[item.id] = {
            edit: false,
            data: { ...item }
          };
        });
      }
    
      ngOnInit(): void {
        for (let i = 0; i < 100; i++) {
          this.listOfData.push({
            id: `${i}`,
            name: `Edrward ${i}`,
            age: 32,
            address: `London Park no. ${i}`
          });
        }
        this.updateEditCache();
      }
    }

    Table表格 - 图20

    嵌套子表格

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

    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-nested-table',
      template: `
        <nz-table #nestedTable [nzData]="listOfParentData" [nzPageSize]="10">
          <thead>
            <tr>
              <th nzShowExpand></th>
              <th>Name</th>
              <th>Platform</th>
              <th>Version</th>
              <th>Upgraded</th>
              <th>Creator</th>
              <th>Date</th>
              <th>Action</th>
            </tr>
          </thead>
          <tbody>
            <ng-template ngFor let-data [ngForOf]="nestedTable.data">
              <tr>
                <td nzShowExpand [(nzExpand)]="data.expand"></td>
                <td>{{ data.name }}</td>
                <td>{{ data.platform }}</td>
                <td>{{ data.version }}</td>
                <td>{{ data.upgradeNum }}</td>
                <td>{{ data.creator }}</td>
                <td>{{ data.createdAt }}</td>
                <td>
                  <a>Publish</a>
                </td>
              </tr>
              <tr [nzExpand]="data.expand">
                <td></td>
                <td colspan="7">
                  <nz-table #innerTable [nzData]="listOfChildrenData" nzSize="middle" [nzShowPagination]="false">
                    <thead>
                      <tr>
                        <th>Date</th>
                        <th>Name</th>
                        <th>Status</th>
                        <th>Upgrade Status</th>
                        <th>Action</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr *ngFor="let data of innerTable.data">
                        <td>{{ data.date }}</td>
                        <td>{{ data.name }}</td>
                        <td>
                          <nz-badge [nzStatus]="'success'" [nzText]="'Finished'"></nz-badge>
                        </td>
                        <td>{{ data.upgradeNum }}</td>
                        <td>
                          <span class="table-operation">
                            <a nz-dropdown class="operation" [nzDropdownMenu]="menu">
                              Pause <i nz-icon nzType="down"></i>
                            </a>
                            <nz-dropdown-menu #menu="nzDropdownMenu">
                              <ul nz-menu>
                                <li nz-menu-item>
                                  <a>Action 1</a>
                                </li>
                                <li nz-menu-item>
                                  <a>Action 2</a>
                                </li>
                              </ul>
                            </nz-dropdown-menu>
                            <nz-divider nzType="vertical"></nz-divider>
                            <a class="operation">Stop</a>
                            <nz-divider nzType="vertical"></nz-divider>
                            <a>More</a>
                          </span>
                        </td>
                      </tr>
                    </tbody>
                  </nz-table>
                </td>
              </tr>
            </ng-template>
          </tbody>
        </nz-table>
      `
    })
    export class NzDemoTableNestedTableComponent implements OnInit {
      listOfParentData: any[] = [];
      listOfChildrenData: any[] = [];
    
      ngOnInit(): void {
        for (let i = 0; i < 3; ++i) {
          this.listOfParentData.push({
            key: i,
            name: 'Screem',
            platform: 'iOS',
            version: '10.3.4.5654',
            upgradeNum: 500,
            creator: 'Jack',
            createdAt: '2014-12-24 23:12:00',
            expand: false
          });
        }
        for (let i = 0; i < 3; ++i) {
          this.listOfChildrenData.push({
            key: i,
            date: '2014-12-24 23:12:00',
            name: 'This is production name',
            upgradeNum: 'Upgraded: 56'
          });
        }
      }
    }

    Table表格 - 图21

    虚拟滚动

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

    import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
    import { NzTableComponent } from 'ng-zorro-antd/table';
    import { Subject } from 'rxjs';
    import { takeUntil } from 'rxjs/operators';
    
    export interface VirtualDataInterface {
      index: number;
      name: string;
      age: number;
      address: string;
    }
    
    @Component({
      selector: 'nz-demo-table-virtual',
      template: `
        <button nz-button (click)="scrollToIndex(200)">Scroll To Index 200</button>
        <br />
        <br />
        <nz-table
          #virtualTable
          nzVirtualScroll
          [nzVirtualItemSize]="54"
          [nzData]="listOfData"
          [nzVirtualForTrackBy]="trackByIndex"
          [nzFrontPagination]="false"
          [nzShowPagination]="false"
          [nzScroll]="{ x: '1300px', y: '240px' }"
        >
          <thead>
            <tr>
              <th nzWidth="200px" nzLeft="0px">Full Name</th>
              <th nzWidth="100px" nzLeft="200px">Age</th>
              <th nzWidth="100px">Index</th>
              <th nzWidth="100px">Column 1</th>
              <th nzWidth="100px">Column 2</th>
              <th nzWidth="100px">Column 3</th>
              <th nzWidth="100px">Column 4</th>
              <th nzWidth="100px">Column 5</th>
              <th nzWidth="100px">Column 6</th>
              <th nzWidth="100px">Column 7</th>
              <th nzWidth="100px">Column 8</th>
              <th nzWidth="100px" nzRight="0px">Action</th>
            </tr>
          </thead>
          <tbody>
            <ng-template nz-virtual-scroll let-data let-index="index">
              <tr>
                <td nzLeft="0px">{{ data.name }} {{ index }}</td>
                <td nzLeft="200px">{{ data.age }}</td>
                <td>{{ data.index }}</td>
                <td>{{ data.address }}</td>
                <td>{{ data.address }}</td>
                <td>{{ data.address }}</td>
                <td>{{ data.address }}</td>
                <td>{{ data.address }}</td>
                <td>{{ data.address }}</td>
                <td>{{ data.address }}</td>
                <td>{{ data.address }}</td>
                <td nzRight="0px">
                  <a>action</a>
                </td>
              </tr>
            </ng-template>
          </tbody>
        </nz-table>
      `
    })
    export class NzDemoTableVirtualComponent implements OnInit, AfterViewInit, OnDestroy {
      @ViewChild('virtualTable', { static: false }) nzTableComponent: NzTableComponent;
      private destroy$ = new Subject();
      listOfData: VirtualDataInterface[] = [];
    
      scrollToIndex(index: number): void {
        this.nzTableComponent.cdkVirtualScrollViewport.scrollToIndex(index);
      }
    
      trackByIndex(_: number, data: VirtualDataInterface): number {
        return data.index;
      }
    
      ngOnInit(): void {
        const data = [];
        for (let i = 0; i < 20000; i++) {
          data.push({
            index: i,
            name: `Edward King`,
            age: 32,
            address: `London`
          });
        }
        this.listOfData = data;
      }
    
      ngAfterViewInit(): void {
        this.nzTableComponent.cdkVirtualScrollViewport.scrolledIndexChange
          .pipe(takeUntil(this.destroy$))
          .subscribe((data: number) => {
            console.log('scroll index to', data);
          });
      }
    
      ngOnDestroy(): void {
        this.destroy$.next();
        this.destroy$.complete();
      }
    }

    Table表格 - 图22

    拖拽排序

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

    import { moveItemInArray, CdkDragDrop } from '@angular/cdk/drag-drop';
    import { Component } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-drag-sorting',
      template: `
        <nz-table [nzData]="listOfData" [nzFrontPagination]="false" [nzShowPagination]="false">
          <thead>
            <tr>
              <th>Name</th>
              <th>Age</th>
              <th>Address</th>
            </tr>
          </thead>
          <tbody cdkDropList (cdkDropListDropped)="drop($event)">
            <tr *ngFor="let data of listOfData" cdkDrag>
              <td>{{ data.name }}</td>
              <td>{{ data.age }}</td>
              <td>{{ data.address }}</td>
            </tr>
          </tbody>
        </nz-table>
      `,
      styles: [
        `
          ::ng-deep .cdk-drag-preview {
            display: table;
          }
    
          ::ng-deep .cdk-drag-placeholder {
            opacity: 0;
          }
        `
      ]
    })
    export class NzDemoTableDragSortingComponent {
      listOfData = [
        {
          key: '1',
          name: 'John Brown',
          age: 32,
          address: 'New York No. 1 Lake Park'
        },
        {
          key: '2',
          name: 'Jim Green',
          age: 42,
          address: 'London No. 1 Lake Park'
        },
        {
          key: '3',
          name: 'Joe Black',
          age: 32,
          address: 'Sidney No. 1 Lake Park'
        }
      ];
    
      drop(event: CdkDragDrop<string[]>): void {
        moveItemInArray(this.listOfData, event.previousIndex, event.currentIndex);
      }
    }

    Table表格 - 图23

    模板用法

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

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-template',
      template: `
        <nz-table nzTemplateMode>
          <thead>
            <tr>
              <th>Company</th>
              <th>Contact</th>
              <th>Country</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Alfreds Futterkiste</td>
              <td>Maria Anders</td>
              <td>Germany</td>
            </tr>
            <tr>
              <td>Centro comercial Moctezuma</td>
              <td>Francisco Chang</td>
              <td>Mexico</td>
            </tr>
            <tr>
              <td>Ernst Handel</td>
              <td>Roland Mendel</td>
              <td>Austria</td>
            </tr>
            <tr>
              <td>Island Trading</td>
              <td>Helen Bennett</td>
              <td>UK</td>
            </tr>
            <tr>
              <td>Laughing Bacchus Winecellars</td>
              <td>Yoshi Tannamuri</td>
              <td>Canada</td>
            </tr>
            <tr>
              <td>Magazzini Alimentari Riuniti</td>
              <td>Giovanni Rovelli</td>
              <td>Italy</td>
            </tr>
          </tbody>
        </nz-table>
      `
    })
    export class NzDemoTableTemplateComponent {}

    Table表格 - 图24

    动态控制表格属性

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

    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'nz-demo-table-dynamic-settings',
      template: `
        <div class="components-table-demo-control-bar">
          <form nz-form nzLayout="inline">
            <nz-form-item>
              <nz-form-label><label>Bordered</label></nz-form-label>
              <nz-form-control><nz-switch [(ngModel)]="bordered" name="bordered"></nz-switch></nz-form-control>
            </nz-form-item>
            <nz-form-item>
              <nz-form-label><label>Loading</label></nz-form-label>
              <nz-form-control><nz-switch [(ngModel)]="loading" name="loading"></nz-switch></nz-form-control>
            </nz-form-item>
            <nz-form-item>
              <nz-form-label><label>Pagination</label></nz-form-label>
              <nz-form-control><nz-switch [(ngModel)]="pagination" name="pagination"></nz-switch></nz-form-control>
            </nz-form-item>
            <nz-form-item>
              <nz-form-label><label>PageSizeChanger</label></nz-form-label>
              <nz-form-control><nz-switch [(ngModel)]="sizeChanger" name="sizeChanger"></nz-switch></nz-form-control>
            </nz-form-item>
            <nz-form-item>
              <nz-form-label><label>Title</label></nz-form-label>
              <nz-form-control><nz-switch [(ngModel)]="title" name="title"></nz-switch></nz-form-control>
            </nz-form-item>
            <nz-form-item>
              <nz-form-label><label>Column Header</label></nz-form-label>
              <nz-form-control><nz-switch [(ngModel)]="header" name="header"></nz-switch></nz-form-control>
            </nz-form-item>
            <nz-form-item>
              <nz-form-label><label>Footer</label></nz-form-label>
              <nz-form-control><nz-switch [(ngModel)]="footer" name="footer"></nz-switch></nz-form-control>
            </nz-form-item>
            <nz-form-item>
              <nz-form-label><label>Expandable</label></nz-form-label>
              <nz-form-control><nz-switch [(ngModel)]="expandable" name="expandable"></nz-switch></nz-form-control>
            </nz-form-item>
            <nz-form-item>
              <nz-form-label><label>Checkbox</label></nz-form-label>
              <nz-form-control><nz-switch [(ngModel)]="checkbox" name="checkbox"></nz-switch></nz-form-control>
            </nz-form-item>
            <nz-form-item>
              <nz-form-label><label>Fixed Header</label></nz-form-label>
              <nz-form-control><nz-switch [(ngModel)]="fixHeader" name="fixHeader"></nz-switch></nz-form-control>
            </nz-form-item>
            <nz-form-item>
              <nz-form-label><label>No Result</label></nz-form-label>
              <nz-form-control
                ><nz-switch [(ngModel)]="noResult" (ngModelChange)="noResultChange($event)" name="noResult"></nz-switch
              ></nz-form-control>
            </nz-form-item>
            <nz-form-item>
              <nz-form-label><label>Simple Pagination</label></nz-form-label>
              <nz-form-control><nz-switch [(ngModel)]="simple" name="simple"></nz-switch></nz-form-control>
            </nz-form-item>
            <nz-form-item>
              <nz-form-label><label>Size</label></nz-form-label>
              <nz-form-control>
                <nz-radio-group [(ngModel)]="size" name="size">
                  <label nz-radio-button nzValue="default">Default</label>
                  <label nz-radio-button nzValue="middle">Middle</label>
                  <label nz-radio-button nzValue="small">Small</label>
                </nz-radio-group>
              </nz-form-control>
            </nz-form-item>
            <nz-form-item>
              <nz-form-label><label>Pagination Position</label></nz-form-label>
              <nz-form-control>
                <nz-radio-group [(ngModel)]="position" name="position">
                  <label nz-radio-button nzValue="top">Top</label>
                  <label nz-radio-button nzValue="bottom">Bottom</label>
                  <label nz-radio-button nzValue="both">Both</label>
                </nz-radio-group>
              </nz-form-control>
            </nz-form-item>
          </form>
        </div>
        <nz-table
          #dynamicTable
          [nzScroll]="fixHeader ? { y: '240px' } : null"
          [nzData]="listOfData"
          [nzBordered]="bordered"
          [nzSimple]="simple"
          [nzLoading]="loading"
          [nzPaginationPosition]="position"
          [nzShowSizeChanger]="sizeChanger"
          [nzFrontPagination]="pagination"
          [nzShowPagination]="pagination"
          [nzFooter]="footer ? 'Here is Footer' : null"
          [nzTitle]="title ? 'Here is Title' : null"
          [nzSize]="size"
          (nzCurrentPageDataChange)="currentPageDataChange($event)"
        >
          <thead>
            <tr *ngIf="header">
              <th nzWidth="50px" nzShowExpand *ngIf="expandable"></th>
              <th
                nzWidth="62px"
                nzShowCheckbox
                *ngIf="checkbox"
                [(nzChecked)]="allChecked"
                [nzIndeterminate]="indeterminate"
                (nzCheckedChange)="checkAll($event)"
              ></th>
              <th nzWidth="150px">Name</th>
              <th nzWidth="70px">Age</th>
              <th>Address</th>
              <th nzWidth="260px">Action</th>
            </tr>
          </thead>
          <tbody>
            <ng-template ngFor let-data [ngForOf]="dynamicTable.data">
              <tr>
                <td nzShowExpand *ngIf="expandable" [(nzExpand)]="data.expand"></td>
                <td nzShowCheckbox *ngIf="checkbox" [(nzChecked)]="data.checked" (nzCheckedChange)="refreshStatus()"></td>
                <td>{{ data.name }}</td>
                <td>{{ data.age }}</td>
                <td>{{ data.address }}</td>
                <td>
                  <a href="#">Action 一 {{ data.name }}</a>
                  <nz-divider nzType="vertical"></nz-divider>
                  <a href="#">Delete</a>
                </td>
              </tr>
              <tr [nzExpand]="data.expand && expandable">
                <td></td>
                <td [attr.colspan]="checkbox ? 5 : 4">{{ data.description }}</td>
              </tr>
            </ng-template>
          </tbody>
        </nz-table>
      `,
      styles: [
        `
          .components-table-demo-control-bar {
            margin-bottom: 12px;
          }
    
          .nz-form-item {
            margin-right: 16px;
            margin-bottom: 8px;
          }
        `
      ]
    })
    export class NzDemoTableDynamicSettingsComponent implements OnInit {
      listOfData: any[] = [];
      bordered = false;
      loading = false;
      sizeChanger = false;
      pagination = true;
      header = true;
      title = true;
      footer = true;
      fixHeader = false;
      size = 'small';
      expandable = true;
      checkbox = true;
      allChecked = false;
      indeterminate = false;
      displayData: any[] = [];
      simple = false;
      noResult = false;
      position = 'bottom';
    
      currentPageDataChange(
        $event: Array<{
          name: string;
          age: number;
          address: string;
          checked: boolean;
          expand: boolean;
          description: string;
        }>
      ): void {
        this.displayData = $event;
        this.refreshStatus();
      }
    
      refreshStatus(): void {
        const validData = this.displayData.filter(value => !value.disabled);
        const allChecked = validData.length > 0 && validData.every(value => value.checked === true);
        const allUnChecked = validData.every(value => !value.checked);
        this.allChecked = allChecked;
        this.indeterminate = !allChecked && !allUnChecked;
      }
    
      checkAll(value: boolean): void {
        this.displayData.forEach(data => {
          if (!data.disabled) {
            data.checked = value;
          }
        });
        this.refreshStatus();
      }
    
      ngOnInit(): void {
        for (let i = 1; i <= 100; i++) {
          this.listOfData.push({
            name: 'John Brown',
            age: `${i}2`,
            address: `New York No. ${i} Lake Park`,
            description: `My name is John Brown, I am ${i}2 years old, living in New York No. ${i} Lake Park.`,
            checked: false,
            expand: false
          });
        }
      }
    
      noResultChange(status: boolean): void {
        this.listOfData = [];
        if (!status) {
          this.ngOnInit();
        }
      }
    }

    API

    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
    [nzVirtualForTrackBy]虚拟滚动数据 TrackByFunction 函数TrackByFunction<T>-
    (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 的数据不会生效

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