Table表格
展示行列数据。
何时使用
- 当有大量结构化的数据需要展现时;
- 当需要对数据进行排序、搜索、分页、自定义操作等复杂行为时。
import { NzTableModule } from 'ng-zorro-antd/table';
如何使用
Table 组件同时具备了易用性和高度可定制性
高度定制
在 nz-table
组件中完整的暴露了 W3C标准 <table>
的所有组成部分,你可以像使用 table
元素一样使用 nz-table
,根据依据业务需求,使用者可以自由的控制任何一个部分的样式、内容、逻辑和事件绑定。
组件增强
在 nz-table
, thead
, th
, td
等多个暴露的元素上,组件提供了增强语法,经过配置之后可以很方便的实现多选、过滤、排序、固定列、固定表头、服务端分页等功能。
数据处理
将数据传入[nzData]
,经过组件处理之后(包括分页、排序、筛选等),通过 模板变量 获取当前展示表格部分的数据,使用 *ngFor
依据需求将数据渲染。
<nz-table #basicTable [nzData]="dataSet">
<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>
代码演示
基本用法
简单的表格,最后一列是各种操作。
import { Component } from '@angular/core';
interface Person {
key: string;
name: string;
age: number;
address: string;
}
@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: Person[] = [
{
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'
}
];
}
选择和操作
第一列是联动的选择框,增加 [nzChecked]
后,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="send-request">
<button nz-button nzType="primary" [disabled]="setOfCheckedId.size === 0" [nzLoading]="loading" (click)="sendRequest()">
Send Request
</button>
<span>Selected {{ setOfCheckedId.size }} items</span>
</div>
<nz-table
#rowSelectionTable
nzShowPagination
nzShowSizeChanger
[nzData]="listOfData"
(nzCurrentPageDataChange)="onCurrentPageDataChange($event)"
>
<thead>
<tr>
<th [nzChecked]="checked" [nzIndeterminate]="indeterminate" (nzCheckedChange)="onAllChecked($event)"></th>
<th>Name</th>
<th>Age</th>
<th>Address</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of rowSelectionTable.data">
<td
[nzChecked]="setOfCheckedId.has(data.id)"
[nzDisabled]="data.disabled"
(nzCheckedChange)="onItemChecked(data.id, $event)"
></td>
<td>{{ data.name }}</td>
<td>{{ data.age }}</td>
<td>{{ data.address }}</td>
</tr>
</tbody>
</nz-table>
`,
styles: [
`
.send-request {
margin-bottom: 16px;
}
.send-request span {
margin-left: 8px;
}
`
]
})
export class NzDemoTableRowSelectionAndOperationComponent implements OnInit {
checked = false;
loading = false;
indeterminate = false;
listOfData: Data[] = [];
listOfCurrentPageData: Data[] = [];
setOfCheckedId = new Set<number>();
updateCheckedSet(id: number, checked: boolean): void {
if (checked) {
this.setOfCheckedId.add(id);
} else {
this.setOfCheckedId.delete(id);
}
}
onCurrentPageDataChange(listOfCurrentPageData: Data[]): void {
this.listOfCurrentPageData = listOfCurrentPageData;
this.refreshCheckedStatus();
}
refreshCheckedStatus(): void {
const listOfEnabledData = this.listOfCurrentPageData.filter(({ disabled }) => !disabled);
this.checked = listOfEnabledData.every(({ id }) => this.setOfCheckedId.has(id));
this.indeterminate = listOfEnabledData.some(({ id }) => this.setOfCheckedId.has(id)) && !this.checked;
}
onItemChecked(id: number, checked: boolean): void {
this.updateCheckedSet(id, checked);
this.refreshCheckedStatus();
}
onAllChecked(checked: boolean): void {
this.listOfCurrentPageData.filter(({ disabled }) => !disabled).forEach(({ id }) => this.updateCheckedSet(id, checked));
this.refreshCheckedStatus();
}
sendRequest(): void {
this.loading = true;
const requestData = this.listOfData.filter(data => this.setOfCheckedId.has(data.id));
console.log(requestData);
setTimeout(() => {
this.setOfCheckedId.clear();
this.refreshCheckedStatus();
this.loading = false;
}, 1000);
}
ngOnInit(): void {
this.listOfData = new Array(100).fill(0).map((_, index) => {
return {
id: index,
name: `Edward King ${index}`,
age: 32,
address: `London, Park Lane no. ${index}`,
disabled: index % 2 === 0
};
});
}
}
自定义选择项
通过 nzSelections
自定义选择项.
import { Component, OnInit } from '@angular/core';
interface ItemData {
id: number;
name: string;
age: number;
address: string;
}
@Component({
selector: 'nz-demo-table-row-selection-custom',
template: `
<nz-table #rowSelectionTable nzShowSizeChanger [nzData]="listOfData" (nzCurrentPageDataChange)="onCurrentPageDataChange($event)">
<thead>
<tr>
<th
[nzSelections]="listOfSelection"
[(nzChecked)]="checked"
[nzIndeterminate]="indeterminate"
(nzCheckedChange)="onAllChecked($event)"
></th>
<th>Name</th>
<th>Age</th>
<th>Address</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of rowSelectionTable.data">
<td [nzChecked]="setOfCheckedId.has(data.id)" (nzCheckedChange)="onItemChecked(data.id, $event)"></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.onAllChecked(true);
}
},
{
text: 'Select Odd Row',
onSelect: () => {
this.listOfCurrentPageData.forEach((data, index) => this.updateCheckedSet(data.id, index % 2 !== 0));
this.refreshCheckedStatus();
}
},
{
text: 'Select Even Row',
onSelect: () => {
this.listOfCurrentPageData.forEach((data, index) => this.updateCheckedSet(data.id, index % 2 === 0));
this.refreshCheckedStatus();
}
}
];
checked = false;
indeterminate = false;
listOfCurrentPageData: ItemData[] = [];
listOfData: ItemData[] = [];
setOfCheckedId = new Set<number>();
updateCheckedSet(id: number, checked: boolean): void {
if (checked) {
this.setOfCheckedId.add(id);
} else {
this.setOfCheckedId.delete(id);
}
}
onItemChecked(id: number, checked: boolean): void {
this.updateCheckedSet(id, checked);
this.refreshCheckedStatus();
}
onAllChecked(value: boolean): void {
this.listOfCurrentPageData.forEach(item => this.updateCheckedSet(item.id, value));
this.refreshCheckedStatus();
}
onCurrentPageDataChange($event: ItemData[]): void {
this.listOfCurrentPageData = $event;
this.refreshCheckedStatus();
}
refreshCheckedStatus(): void {
this.checked = this.listOfCurrentPageData.every(item => this.setOfCheckedId.has(item.id));
this.indeterminate = this.listOfCurrentPageData.some(item => this.setOfCheckedId.has(item.id)) && !this.checked;
}
ngOnInit(): void {
this.listOfData = new Array(200).fill(0).map((_, index) => {
return {
id: index,
name: `Edward King ${index}`,
age: 32,
address: `London, Park Lane no. ${index}`
};
});
}
}
筛选和排序
筛选:对某一列数据进行筛选,通过指定 [nzFilters]
属性来指定筛选菜单,[nzFilterFn]
指定筛选函数,[nzFilterMultiple]
用于指定多选和单选,通过设置 [nzFilters]
中的 { byDefault: true }
属性来默认启用一个筛选器。
排序:对某一列数据进行排序,通过指定 [nzSortOrder]
来指定默认排序顺序,[nzSortFn]
指定排序函数 [nzSortDirections]
改变每列可用的排序方式。
import { Component } from '@angular/core';
import { NzTableFilterFn, NzTableFilterList, NzTableSortFn, NzTableSortOrder } from 'ng-zorro-antd/table';
interface DataItem {
name: string;
age: number;
address: string;
}
interface ColumnItem {
name: string;
sortOrder: NzTableSortOrder | null;
sortFn: NzTableSortFn | null;
listOfFilter: NzTableFilterList;
filterFn: NzTableFilterFn | null;
filterMultiple: boolean;
sortDirections: NzTableSortOrder[];
}
@Component({
selector: 'nz-demo-table-sort-filter',
template: `
<nz-table #filterTable [nzData]="listOfData" nzTableLayout="fixed">
<thead>
<tr>
<th
*ngFor="let column of listOfColumns"
[nzSortOrder]="column.sortOrder"
[nzSortFn]="column.sortFn"
[nzSortDirections]="column.sortDirections"
[nzFilterMultiple]="column.filterMultiple"
[nzFilters]="column.listOfFilter"
[nzFilterFn]="column.filterFn"
>
{{ column.name }}
</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 NzDemoTableSortFilterComponent {
listOfColumns: ColumnItem[] = [
{
name: 'Name',
sortOrder: null,
sortFn: (a: DataItem, b: DataItem) => a.name.localeCompare(b.name),
sortDirections: ['ascend', 'descend', null],
filterMultiple: true,
listOfFilter: [
{ text: 'Joe', value: 'Joe' },
{ text: 'Jim', value: 'Jim', byDefault: true }
],
filterFn: (list: string[], item: DataItem) => list.some(name => item.name.indexOf(name) !== -1)
},
{
name: 'Age',
sortOrder: 'descend',
sortFn: (a: DataItem, b: DataItem) => a.age - b.age,
sortDirections: ['descend', null],
listOfFilter: [],
filterFn: null,
filterMultiple: true
},
{
name: 'Address',
sortOrder: null,
sortDirections: ['ascend', 'descend', null],
sortFn: (a: DataItem, b: DataItem) => a.address.length - b.address.length,
filterMultiple: false,
listOfFilter: [
{ text: 'London', value: 'London' },
{ text: 'Sidney', value: 'Sidney' }
],
filterFn: (address: string, item: DataItem) => item.address.indexOf(address) !== -1
}
];
listOfData: DataItem[] = [
{
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'
}
];
}
多列排序
使用 [nzSortPriority]
字段以配置多列排序优先级。通过 [nzSortFn]
配置排序逻辑。
import { Component } from '@angular/core';
interface DataItem {
name: string;
chinese: number;
math: number;
english: number;
}
@Component({
selector: 'nz-demo-table-multiple-sorter',
template: `
<nz-table #sortTable [nzData]="listOfData" nzTableLayout="fixed">
<thead>
<tr>
<th *ngFor="let column of listOfColumn" [nzSortFn]="column.compare" [nzSortPriority]="column.priority">{{ column.title }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of sortTable.data">
<td>{{ data.name }}</td>
<td>{{ data.chinese }}</td>
<td>{{ data.math }}</td>
<td>{{ data.english }}</td>
</tr>
</tbody>
</nz-table>
`
})
export class NzDemoTableMultipleSorterComponent {
listOfColumn = [
{
title: 'Name',
compare: null,
priority: false
},
{
title: 'Chinese Score',
compare: (a: DataItem, b: DataItem) => a.chinese - b.chinese,
priority: 3
},
{
title: 'Math Score',
compare: (a: DataItem, b: DataItem) => a.math - b.math,
priority: 2
},
{
title: 'English Score',
compare: (a: DataItem, b: DataItem) => a.english - b.english,
priority: 1
}
];
listOfData: DataItem[] = [
{
name: 'John Brown',
chinese: 98,
math: 60,
english: 70
},
{
name: 'Jim Green',
chinese: 98,
math: 66,
english: 89
},
{
name: 'Joe Black',
chinese: 98,
math: 90,
english: 70
},
{
name: 'Jim Red',
chinese: 88,
math: 99,
english: 89
}
];
}
可控的筛选和排序
修改 [nzSortOrder]
和 [nzFilters]
来指定当前列的排序与筛选状态。
import { Component } from '@angular/core';
import { NzTableFilterFn, NzTableFilterList, NzTableSortFn, NzTableSortOrder } from 'ng-zorro-antd/table';
interface DataItem {
name: string;
age: number;
address: string;
}
interface ColumnItem {
name: string;
sortOrder: NzTableSortOrder | null;
sortFn: NzTableSortFn | null;
listOfFilter: NzTableFilterList;
filterFn: NzTableFilterFn | null;
}
@Component({
selector: 'nz-demo-table-reset-filter',
template: `
<div class="table-operations">
<button nz-button (click)="sortByAge()">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]="listOfData" nzTableLayout="fixed">
<thead>
<tr>
<th
*ngFor="let column of listOfColumns; trackBy: trackByName"
[(nzSortOrder)]="column.sortOrder"
[nzSortFn]="column.sortFn"
[nzFilters]="column.listOfFilter"
[nzFilterFn]="column.filterFn"
>
{{ column.name }}
</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 {
listOfColumns: ColumnItem[] = [
{
name: 'Name',
sortOrder: null,
sortFn: (a: DataItem, b: DataItem) => a.name.localeCompare(b.name),
listOfFilter: [
{ text: 'Joe', value: 'Joe' },
{ text: 'Jim', value: 'Jim' }
],
filterFn: (list: string[], item: DataItem) => list.some(name => item.name.indexOf(name) !== -1)
},
{
name: 'Age',
sortOrder: null,
sortFn: (a: DataItem, b: DataItem) => a.age - b.age,
listOfFilter: [],
filterFn: null
},
{
name: 'Address',
sortFn: null,
sortOrder: null,
listOfFilter: [
{ text: 'London', value: 'London' },
{ text: 'Sidney', value: 'Sidney' }
],
filterFn: (address: string, item: DataItem) => item.address.indexOf(address) !== -1
}
];
listOfData: DataItem[] = [
{
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'
}
];
trackByName(_: number, item: ColumnItem): string {
return item.name;
}
sortByAge(): void {
this.listOfColumns.forEach(item => {
if (item.name === 'Age') {
item.sortOrder = 'descend';
} else {
item.sortOrder = null;
}
});
}
resetFilters(): void {
this.listOfColumns.forEach(item => {
if (item.name === 'Name') {
item.listOfFilter = [
{ text: 'Joe', value: 'Joe' },
{ text: 'Jim', value: 'Jim' }
];
} else if (item.name === 'Address') {
item.listOfFilter = [
{ text: 'London', value: 'London' },
{ text: 'Sidney', value: 'Sidney' }
];
}
});
}
resetSortAndFilters(): void {
this.listOfColumns.forEach(item => {
item.sortOrder = null;
});
this.resetFilters();
}
}
自定义筛选菜单
通过 <nz-filter-trigger>
组件定义自定义的列筛选功能,并实现一个搜索列的示例。
import { Component } from '@angular/core';
interface DataItem {
name: string;
age: number;
address: string;
}
@Component({
selector: 'nz-demo-table-custom-filter-panel',
template: `
<nz-table #nzTable [nzData]="listOfDisplayData" nzTableLayout="fixed">
<thead>
<tr>
<th nzCustomFilter>
Name
<nz-filter-trigger [(nzVisible)]="visible" [nzActive]="searchValue.length > 0" [nzDropdownMenu]="menu">
<i nz-icon nzType="search"></i>
</nz-filter-trigger>
</th>
<th>Age</th>
<th>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="ant-table-filter-dropdown">
<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>
</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 = '';
visible = false;
listOfData: DataItem[] = [
{
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();
}
search(): void {
this.visible = false;
this.listOfDisplayData = this.listOfData.filter((item: DataItem) => item.name.indexOf(this.searchValue) !== -1);
}
}
远程加载数据
这个例子通过简单的 ajax 读取方式,演示了如何从服务端读取并展现数据,具有筛选、排序等功能以及页面 loading 效果。开发者可以自行接入其他数据处理方式。
- 分页:使用
[nzFrontPagination]="false"
指定由服务端分页。 - 排序:使用
[nzSortFn]="true"
指定由服务端排序,如果需要多列排序可使用[nzSortPriority]="true"
。 - 筛选:使用
[nzFilters]
来指定筛选项,使用[nzFilterFn]="true"
指定由服务端筛选 - 参数传输:通过
(nzQueryParams)
服务端需要的参数,数据结构为
{
pageIndex: number;
pageSize: number;
sort: Array<{ key: string; value: 'ascend' | 'descend' | null }>;
filter: Array<{ key: string; value: any | any[] }>;
}
注意,此示例使用 模拟接口,展示数据可能不准确,请打开网络面板查看请求。
import { HttpClient, HttpParams } from '@angular/common/http';
import { Component, Injectable, OnInit } from '@angular/core';
import { NzTableQueryParams } from 'ng-zorro-antd/table';
import { Observable } from 'rxjs';
interface RandomUser {
gender: string;
email: string;
name: {
title: string;
first: string;
last: string;
};
}
@Injectable({ providedIn: 'root' })
export class RandomUserService {
randomUserUrl = 'https://api.randomuser.me/';
getUsers(
pageIndex: number,
pageSize: number,
sortField: string | null,
sortOrder: string | null,
filters: Array<{ key: string; value: string[] }>
): Observable<{ results: RandomUser[] }> {
let params = new HttpParams()
.append('page', `${pageIndex}`)
.append('results', `${pageSize}`)
.append('sortField', `${sortField}`)
.append('sortOrder', `${sortOrder}`);
filters.forEach(filter => {
filter.value.forEach(value => {
params = params.append(filter.key, value);
});
});
return this.http.get<{ results: RandomUser[] }>(`${this.randomUserUrl}`, { params });
}
constructor(private http: HttpClient) {}
}
@Component({
selector: 'nz-demo-table-ajax',
template: `
<nz-table
nzShowSizeChanger
[nzData]="listOfRandomUser"
[nzFrontPagination]="false"
[nzLoading]="loading"
[nzTotal]="total"
[nzPageSize]="pageSize"
[nzPageIndex]="pageIndex"
(nzQueryParams)="onQueryParamsChange($event)"
>
<thead>
<tr>
<th nzColumnKey="name" [nzSortFn]="true">Name</th>
<th nzColumnKey="gender" [nzFilters]="filterGender" [nzFilterFn]="true">Gender</th>
<th nzColumnKey="email" [nzSortFn]="true">Email</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of listOfRandomUser">
<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 {
total = 1;
listOfRandomUser: RandomUser[] = [];
loading = true;
pageSize = 10;
pageIndex = 1;
filterGender = [
{ text: 'male', value: 'male' },
{ text: 'female', value: 'female' }
];
loadDataFromServer(
pageIndex: number,
pageSize: number,
sortField: string | null,
sortOrder: string | null,
filter: Array<{ key: string; value: string[] }>
): void {
this.loading = true;
this.randomUserService.getUsers(pageIndex, pageSize, sortField, sortOrder, filter).subscribe(data => {
this.loading = false;
this.total = 200; // mock the total data here
this.listOfRandomUser = data.results;
});
}
onQueryParamsChange(params: NzTableQueryParams): void {
console.log(params);
const { pageSize, pageIndex, sort, filter } = params;
const currentSort = sort.find(item => item.value !== null);
const sortField = (currentSort && currentSort.key) || null;
const sortOrder = (currentSort && currentSort.value) || null;
this.loadDataFromServer(pageIndex, pageSize, sortField, sortOrder, filter);
}
constructor(private randomUserService: RandomUserService) {}
ngOnInit(): void {
this.loadDataFromServer(this.pageIndex, this.pageSize, null, null, []);
}
}
紧凑型
两种紧凑型的列表,小型列表只用于对话框内。
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 = [
{
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'
}
];
}
带边框
添加表格边框线,页头和页脚。
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>
<nz-table #outBordered nzOuterBordered 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 outBordered.data">
<td>{{ data.name }}</td>
<td>{{ data.age }}</td>
<td>{{ data.address }}</td>
</tr>
</tbody>
</nz-table>
`
})
export class NzDemoTableBorderedComponent {
dataSet = [
{
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'
}
];
}
可展开
当表格内容较多不能一次性完全展示时,可以通过 td
上的 nzExpand
属性展开。
import { Component } from '@angular/core';
@Component({
selector: 'nz-demo-table-expand',
template: `
<nz-table #nzTable [nzData]="listOfData" nzTableLayout="fixed">
<thead>
<tr>
<th nzWidth="60px"></th>
<th>Name</th>
<th>Age</th>
<th>Address</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let data of nzTable.data">
<tr>
<td [nzExpand]="expandSet.has(data.id)" (nzExpandChange)="onExpandChange(data.id, $event)"></td>
<td>{{ data.name }}</td>
<td>{{ data.age }}</td>
<td>{{ data.address }}</td>
</tr>
<tr [nzExpand]="expandSet.has(data.id)">
<span>{{ data.description }}</span>
</tr>
</ng-container>
</tbody>
</nz-table>
`
})
export class NzDemoTableExpandComponent {
expandSet = new Set<number>();
onExpandChange(id: number, checked: boolean): void {
if (checked) {
this.expandSet.add(id);
} else {
this.expandSet.delete(id);
}
}
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.'
}
];
}
表格行/列合并
像 W3C标准 <table>
一样,使用 colspan
和 rowspan
合并行/列。
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>
<ng-container [ngSwitch]="i">
<ng-container *ngSwitchCase="2">
<td>{{ data.age }}</td>
<td rowspan="2">{{ data.tel }}</td>
<td>{{ data.phone }}</td>
<td>{{ data.address }}</td>
</ng-container>
<ng-container *ngSwitchCase="3">
<td>{{ data.age }}</td>
<td>{{ data.phone }}</td>
<td>{{ data.address }}</td>
</ng-container>
<ng-container *ngSwitchCase="4">
<td colspan="5">{{ data.age }}</td>
</ng-container>
<ng-container *ngSwitchDefault>
<td>{{ data.age }}</td>
<td>{{ data.tel }}</td>
<td>{{ data.phone }}</td>
<td>{{ data.address }}</td>
</ng-container>
</ng-container>
</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'
}
];
}
树形数据展示
表格支持树形数据的展示,可以通过设置 nzIndentSize
以控制每一层的缩进宽度,本例子中提供了树与数组之间的转换函数,实际业务中请根据需求修改。
import { Component, OnInit } from '@angular/core';
export interface TreeNodeInterface {
key: string;
name: string;
age?: number;
level?: number;
expand?: boolean;
address?: string;
children?: TreeNodeInterface[];
parent?: TreeNodeInterface;
}
@Component({
selector: 'nz-demo-table-expand-children',
template: `
<nz-table #expandTable [nzData]="listOfMapData" nzTableLayout="fixed">
<thead>
<tr>
<th>Name</th>
<th>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: TreeNodeInterface[] = [
{
key: `1`,
name: 'John Brown sr.',
age: 60,
address: 'New York No. 1 Lake Park',
children: [
{
key: `1-1`,
name: 'John Brown',
age: 42,
address: 'New York No. 2 Lake Park'
},
{
key: `1-2`,
name: 'John Brown jr.',
age: 30,
address: 'New York No. 3 Lake Park',
children: [
{
key: `1-2-1`,
name: 'Jimmy Brown',
age: 16,
address: 'New York No. 3 Lake Park'
}
]
},
{
key: `1-3`,
name: 'Jim Green sr.',
age: 72,
address: 'London No. 1 Lake Park',
children: [
{
key: `1-3-1`,
name: 'Jim Green',
age: 42,
address: 'London No. 2 Lake Park',
children: [
{
key: `1-3-1-1`,
name: 'Jim Green jr.',
age: 25,
address: 'London No. 3 Lake Park'
},
{
key: `1-3-1-2`,
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) {
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: TreeNodeInterface): TreeNodeInterface[] {
const stack: TreeNodeInterface[] = [];
const array: TreeNodeInterface[] = [];
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]: boolean }, 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);
});
}
}
固定表头
指定 [nzScroll]
的 y
数值 方便一页内展示大量数据,每一列的宽度可以由 [nzWidth]
指定。
import { Component, OnInit } from '@angular/core';
interface ItemData {
name: string;
age: number;
address: string;
}
@Component({
selector: 'nz-demo-table-fixed-header',
template: `
<nz-table #headerTable [nzData]="listOfData" [nzPageSize]="50" [nzScroll]="{ y: '240px' }">
<thead>
<tr>
<th>Name</th>
<th nzWidth="100px">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: ItemData[] = [];
ngOnInit(): void {
const data = [];
for (let i = 0; i < 100; i++) {
data.push({
name: `Edward King ${i}`,
age: 32,
address: `London, Park Lane no. ${i}`
});
}
this.listOfData = data;
}
}
固定列
对于列数很多的数据,可以使用 [nzLeft]
和 [nzRight]
固定前后的列,横向滚动查看其它数据,需要和 [nzScroll].x
配合使用。
列头与内容不对齐或出现列重复,请指定固定列的宽度
[nzWidth]
。如果指定 width 不生效或出现白色垂直空隙,请尝试建议留一列不设宽度以适应弹性布局,或者检查是否有超长连续字段破坏布局。 建议指定nzScroll.x
为大于表格宽度的固定值或百分比。注意,且非固定列宽度之和不要超过nzScroll.x
。 注意:固定列通过 sticky 实现,IE 11 会降级成横向滚动。
import { Component } from '@angular/core';
@Component({
selector: 'nz-demo-table-fixed-columns',
template: `
<nz-table #columnTable [nzData]="listOfData" [nzScroll]="{ x: '1100px' }">
<thead>
<tr>
<th nzLeft>Full Name</th>
<th nzLeft>Age</th>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
<th>Column 7</th>
<th nzRight>Column 8</th>
<th nzRight>Action</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of columnTable.data">
<td nzLeft>{{ data.name }}</td>
<td nzLeft>{{ 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>{{ data.address }}</td>
<td nzRight>
<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'
}
];
}
固定头和列
同时固定头和列,适合同时展示有大量数据和数据列。
列头与内容不对齐或出现列重复,请指定固定列的宽度
[nzWidth]
。如果指定 width 不生效或出现白色垂直空隙,请尝试建议留一列不设宽度以适应弹性布局,或者检查是否有超长连续字段破坏布局。 建议指定nzScroll.x
为大于表格宽度的固定值或百分比。注意,且非固定列宽度之和不要超过nzScroll.x
。 注意:固定列通过 sticky 实现,IE 11 会降级成横向滚动。
import { Component, OnInit } from '@angular/core';
interface ItemData {
name: string;
age: number;
address: string;
}
@Component({
selector: 'nz-demo-table-fixed-columns-header',
template: `
<nz-table #fixedTable [nzData]="listOfData" [nzScroll]="{ x: '1150px', y: '240px' }">
<thead>
<tr>
<th nzLeft>Full Name</th>
<th nzLeft>Age</th>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
<th>Column 7</th>
<th>Column 8</th>
<th nzRight>Action</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of fixedTable.data">
<td nzLeft>{{ data.name }}</td>
<td nzLeft>{{ 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>
<a>action</a>
</td>
</tr>
</tbody>
</nz-table>
`
})
export class NzDemoTableFixedColumnsHeaderComponent implements OnInit {
listOfData: ItemData[] = [];
ngOnInit(): void {
for (let i = 0; i < 100; i++) {
this.listOfData.push({
name: `Edward King ${i}`,
age: 32,
address: `London`
});
}
}
}
表头分组
固定列与分组表头联合使用。
import { Component, OnInit } from '@angular/core';
interface DataItem {
name: string;
age: number;
street: string;
building: string;
number: number;
companyAddress: string;
companyName: string;
gender: string;
}
@Component({
selector: 'nz-demo-table-grouping-columns',
template: `
<nz-table #groupingTable [nzData]="listOfData" nzBordered nzSize="middle" [nzScroll]="{ x: '1200px', y: '240px' }">
<thead>
<tr>
<th rowspan="4" nzLeft [nzFilters]="filterName" [nzFilterFn]="nameFilterFn">Name</th>
<th colspan="4">Other</th>
<th colspan="2">Company</th>
<th rowspan="4" nzRight>Gender</th>
</tr>
<tr>
<th rowspan="3" [nzSortFn]="sortAgeFn">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>{{ 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>{{ data.gender }}</td>
</tr>
</tbody>
</nz-table>
`
})
export class NzDemoTableGroupingColumnsComponent implements OnInit {
listOfData: DataItem[] = [];
sortAgeFn = (a: DataItem, b: DataItem) => a.age - b.age;
nameFilterFn = (list: string[], item: DataItem) => list.some(name => item.name.indexOf(name) !== -1);
filterName = [
{ text: 'Joe', value: 'Joe' },
{ text: 'John', value: 'John' }
];
ngOnInit(): void {
const data = [];
for (let i = 0; i < 100; i++) {
data.push({
name: 'John Brown',
age: i + 1,
street: 'Lake Park',
building: 'C',
number: 2035,
companyAddress: 'Lake Street 42',
companyName: 'SoftLake Co',
gender: 'M'
});
}
this.listOfData = data;
}
}
可编辑单元格
定制带单元格编辑功能的表格,自由操作单元格内容。
为了获得更好的性能,NG-ZORRO 所有组件都运行在 OnPush 模式下,这意味着对
@Input()
数据的 mutate 将不会生效,请使用 immutable 方式操作数组或者对象。开发者可以参照该例子根据自己需求自由定制表格的编辑功能。
import { Component, OnInit } from '@angular/core';
interface ItemData {
id: string;
name: string;
age: string;
address: string;
}
@Component({
selector: 'nz-demo-table-edit-cell',
template: `
<button nz-button (click)="addRow()" nzType="primary">Add</button>
<br />
<br />
<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" [hidden]="editId === data.id" (click)="startEdit(data.id)">
{{ data.name }}
</div>
<input [hidden]="editId !== data.id" type="text" nz-input [(ngModel)]="data.name" (blur)="stopEdit()" />
</td>
<td>{{ data.age }}</td>
<td>{{ data.address }}</td>
<td>
<a nz-popconfirm nzPopconfirmTitle="Sure to delete?" (nzOnConfirm)="deleteRow(data.id)">Delete</a>
</td>
</tr>
</tbody>
</nz-table>
`,
styles: [
`
.editable-cell {
position: relative;
padding: 5px 12px;
cursor: pointer;
}
.editable-row:hover .editable-cell {
border: 1px solid #d9d9d9;
border-radius: 4px;
padding: 4px 11px;
}
`
]
})
export class NzDemoTableEditCellComponent implements OnInit {
i = 0;
editId: string | null = null;
listOfData: ItemData[] = [];
startEdit(id: string): void {
this.editId = id;
}
stopEdit(): void {
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);
}
ngOnInit(): void {
this.addRow();
this.addRow();
}
}
可编辑行
定制带行编辑功能的表格,自由操作行内容。
为了获得更好的性能,NG-ZORRO 所有组件都运行在 OnPush 模式下,这意味着对
@Input()
数据的 mutate 将不会生效,请使用 immutable 方式操作数组或者对象。开发者可以参照该例子根据自己需求自由定制表格的编辑功能。
import { Component, OnInit } from '@angular/core';
interface ItemData {
id: string;
name: string;
age: number;
address: string;
}
@Component({
selector: 'nz-demo-table-edit-row',
template: `
<nz-table #editRowTable nzBordered [nzData]="listOfData" nzTableLayout="fixed">
<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">
<ng-container *ngIf="!editCache[data.id].edit; else editTemplate">
<td>{{ data.name }}</td>
<td>{{ data.age }}</td>
<td>{{ data.address }}</td>
<td><a (click)="startEdit(data.id)">Edit</a></td>
</ng-container>
<ng-template #editTemplate>
<td><input type="text" nz-input [(ngModel)]="editCache[data.id].data.name" /></td>
<td><input type="text" nz-input [(ngModel)]="editCache[data.id].data.age" /></td>
<td><input type="text" nz-input [(ngModel)]="editCache[data.id].data.address" /></td>
<td>
<a (click)="saveEdit(data.id)" class="save">Save</a>
<a nz-popconfirm nzTitle="Sure to cancel?" (nzOnConfirm)="cancelEdit(data.id)">Cancel</a>
</td>
</ng-template>
</tr>
</tbody>
</nz-table>
`,
styles: [
`
.save {
margin-right: 8px;
}
`
]
})
export class NzDemoTableEditRowComponent implements OnInit {
editCache: { [key: string]: { edit: boolean; data: ItemData } } = {};
listOfData: ItemData[] = [];
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 {
const data = [];
for (let i = 0; i < 100; i++) {
data.push({
id: `${i}`,
name: `Edrward ${i}`,
age: 32,
address: `London Park no. ${i}`
});
}
this.listOfData = data;
this.updateEditCache();
}
}
嵌套子表格
展示每行数据更详细的信息。
import { Component, OnInit } from '@angular/core';
interface ParentItemData {
key: number;
name: string;
platform: string;
version: string;
upgradeNum: number | string;
creator: string;
createdAt: string;
expand: boolean;
}
interface ChildrenItemData {
key: number;
name: string;
date: string;
upgradeNum: string;
}
@Component({
selector: 'nz-demo-table-nested-table',
template: `
<nz-table #nestedTable [nzData]="listOfParentData" [nzPageSize]="10">
<thead>
<tr>
<th></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 [(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">
<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>
</tr>
</ng-template>
</tbody>
</nz-table>
`
})
export class NzDemoTableNestedTableComponent implements OnInit {
listOfParentData: ParentItemData[] = [];
listOfChildrenData: ChildrenItemData[] = [];
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'
});
}
}
}
虚拟滚动
虚拟滚动,结合 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
[nzVirtualItemSize]="54"
[nzData]="listOfData"
[nzVirtualForTrackBy]="trackByIndex"
[nzFrontPagination]="false"
[nzShowPagination]="false"
[nzScroll]="{ x: '1200px', y: '240px' }"
>
<thead>
<tr>
<th nzLeft>Full Name</th>
<th nzLeft>Age</th>
<th>Index</th>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
<th>Column 7</th>
<th>Column 8</th>
<th nzRight>Action</th>
</tr>
</thead>
<tbody>
<ng-template nz-virtual-scroll let-data let-index="index">
<tr>
<td nzLeft>{{ data.name }}</td>
<td nzLeft>{{ 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>
<a>action</a>
</td>
</tr>
</ng-template>
</tbody>
</nz-table>
`
})
export class NzDemoTableVirtualComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChild('virtualTable', { static: false }) nzTableComponent?: NzTableComponent<VirtualDataInterface>;
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`,
age: i,
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();
}
}
拖拽排序
使用自定义元素,用户可以导入 @angular/cdk/drag-drop 来实现拖拽排序。
注意:需要手动导入
import {DragDropModule} from '@angular/cdk/drag-drop'
;
import { CdkDragDrop, moveItemInArray } 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);
}
}
模板用法
模板模式,显示内容仅由模板内容控制,不再需要向 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 {}
折行显示
当有连续超长字符串时,可以使用 nzBreakWord
来折行显示
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'nz-demo-table-break-word',
template: `
<nz-table #fixedTable [nzData]="listOfData" [nzScroll]="{ x: '1000px', y: '240px' }">
<thead>
<tr>
<th nzLeft>Full Name</th>
<th nzLeft>Age</th>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
<th>Column 7</th>
<th>Column 8</th>
<th nzRight>Action</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of fixedTable.data">
<td nzLeft>{{ data.name }}</td>
<td nzLeft>{{ data.age }}</td>
<td nzBreakWord>{{ data.address }}</td>
<td nzBreakWord>{{ data.address }}</td>
<td nzBreakWord>{{ data.address }}</td>
<td nzBreakWord>{{ data.address }}</td>
<td nzBreakWord>{{ data.address }}</td>
<td nzBreakWord>{{ data.address }}</td>
<td nzBreakWord>{{ data.address }}</td>
<td nzBreakWord>{{ data.address }}</td>
<td nzRight>
<a>action</a>
</td>
</tr>
</tbody>
</nz-table>
`
})
export class NzDemoTableBreakWordComponent implements OnInit {
listOfData: Array<{ name: string; age: number; address: string }> = [];
ngOnInit(): void {
for (let i = 0; i < 100; i++) {
this.listOfData.push({
name: `Edward King`,
age: 32,
address: `LondonLondonLondonLondonLondon`
});
}
}
}
单元格自动省略
设置 nzTableLayout="fixed"
与 nzEllipsis
可以让单元格内容根据宽度自动省略。
列头缩略暂不支持和排序筛选一起使用。
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'nz-demo-table-ellipsis',
template: `
<nz-table #fixedTable [nzData]="listOfData" nzTableLayout="fixed">
<thead>
<tr>
<th>Full Name</th>
<th>Age</th>
<th>Column 1</th>
<th>Column 2</th>
<th nzEllipsis>Column ColumnColumn 3</th>
<th>Column 4</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of fixedTable.data">
<td>{{ data.name }}</td>
<td>{{ data.age }}</td>
<td nzEllipsis>{{ data.address }}</td>
<td nzEllipsis>{{ data.address }}</td>
<td nzEllipsis>{{ data.address }}</td>
<td nzEllipsis>{{ data.address }}</td>
</tr>
</tbody>
</nz-table>
`
})
export class NzDemoTableEllipsisComponent implements OnInit {
listOfData: Array<{ name: string; age: number; address: string }> = [];
ngOnInit(): void {
for (let i = 0; i < 3; i++) {
this.listOfData.push({
name: `Edward King`,
age: 32,
address: `LondonLondonLondonLondonLondon`
});
}
}
}
动态控制表格属性
选择不同配置组合查看效果。
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { NzTableLayout, NzTablePaginationPosition, NzTableSize } from 'ng-zorro-antd/table';
interface ItemData {
name: string;
age: number | string;
address: string;
checked: boolean;
expand: boolean;
description: string;
disabled?: boolean;
}
interface Setting {
bordered: boolean;
loading: boolean;
pagination: boolean;
sizeChanger: boolean;
title: boolean;
header: boolean;
footer: boolean;
expandable: boolean;
checkbox: boolean;
fixHeader: boolean;
noResult: boolean;
ellipsis: boolean;
simple: boolean;
size: NzTableSize;
tableScroll: string;
tableLayout: NzTableLayout;
position: NzTablePaginationPosition;
}
@Component({
selector: 'nz-demo-table-dynamic-settings',
template: `
<div class="components-table-demo-control-bar">
<form nz-form nzLayout="inline" [formGroup]="settingForm!">
<nz-form-item *ngFor="let switch of listOfSwitch">
<nz-form-label> {{ switch.name }} </nz-form-label>
<nz-form-control><nz-switch [formControlName]="switch.formControlName"></nz-switch></nz-form-control>
</nz-form-item>
<nz-form-item *ngFor="let radio of listOfRadio">
<nz-form-label> {{ radio.name }} </nz-form-label>
<nz-form-control>
<nz-radio-group [formControlName]="radio.formControlName">
<label *ngFor="let o of radio.listOfOption" nz-radio-button [nzValue]="o.value">{{ o.label }}</label>
</nz-radio-group>
</nz-form-control>
</nz-form-item>
</form>
</div>
<nz-table
#dynamicTable
[nzScroll]="{ x: scrollX, y: scrollY }"
[nzData]="listOfData"
[nzTableLayout]="settingValue.tableLayout"
[nzBordered]="settingValue.bordered"
[nzSimple]="settingValue.simple"
[nzLoading]="settingValue.loading"
[nzPaginationPosition]="settingValue.position"
[nzShowSizeChanger]="settingValue.sizeChanger"
[nzFrontPagination]="settingValue.pagination"
[nzShowPagination]="settingValue.pagination"
[nzFooter]="settingValue.footer ? 'Here is Footer' : null"
[nzTitle]="settingValue.title ? 'Here is Title' : null"
[nzSize]="settingValue.size"
(nzCurrentPageDataChange)="currentPageDataChange($event)"
>
<thead>
<tr *ngIf="settingValue.header">
<th nzWidth="40px" *ngIf="settingValue.expandable" [nzLeft]="fixedColumn"></th>
<th
*ngIf="settingValue.checkbox"
nzWidth="60px"
[(nzChecked)]="allChecked"
[nzLeft]="fixedColumn"
[nzIndeterminate]="indeterminate"
(nzCheckedChange)="checkAll($event)"
></th>
<th [nzLeft]="fixedColumn">Name</th>
<th>Age</th>
<th>Address</th>
<th [nzRight]="fixedColumn">Action</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let data of dynamicTable.data">
<tr>
<td [nzLeft]="fixedColumn" *ngIf="settingValue.expandable" [(nzExpand)]="data.expand"></td>
<td [nzLeft]="fixedColumn" *ngIf="settingValue.checkbox" [(nzChecked)]="data.checked" (nzCheckedChange)="refreshStatus()"></td>
<td [nzLeft]="fixedColumn">{{ data.name }}</td>
<td>{{ data.age }}</td>
<td [nzEllipsis]="settingValue.ellipsis">{{ data.address }}</td>
<td [nzRight]="fixedColumn" [nzEllipsis]="settingValue.ellipsis">
<a href="#">Delete</a>
<nz-divider nzType="vertical"></nz-divider>
<a href="#">More action</a>
</td>
</tr>
<tr *ngIf="settingValue.expandable" [nzExpand]="data.expand">
<span> {{ data.description }}</span>
</tr>
</ng-container>
</tbody>
</nz-table>
`,
styles: [
`
form nz-form-item {
margin-right: 16px;
margin-bottom: 8px;
}
`
]
})
export class NzDemoTableDynamicSettingsComponent implements OnInit {
settingForm?: FormGroup;
listOfData: ItemData[] = [];
displayData: ItemData[] = [];
allChecked = false;
indeterminate = false;
fixedColumn = false;
scrollX: string | null = null;
scrollY: string | null = null;
settingValue!: Setting;
listOfSwitch = [
{ name: 'Bordered', formControlName: 'bordered' },
{ name: 'Loading', formControlName: 'loading' },
{ name: 'Pagination', formControlName: 'pagination' },
{ name: 'PageSizeChanger', formControlName: 'sizeChanger' },
{ name: 'Title', formControlName: 'title' },
{ name: 'Column Header', formControlName: 'header' },
{ name: 'Footer', formControlName: 'footer' },
{ name: 'Expandable', formControlName: 'expandable' },
{ name: 'Checkbox', formControlName: 'checkbox' },
{ name: 'Fixed Header', formControlName: 'fixHeader' },
{ name: 'No Result', formControlName: 'noResult' },
{ name: 'Ellipsis', formControlName: 'ellipsis' },
{ name: 'Simple Pagination', formControlName: 'simple' }
];
listOfRadio = [
{
name: 'Size',
formControlName: 'size',
listOfOption: [
{ value: 'default', label: 'Default' },
{ value: 'middle', label: 'Middle' },
{ value: 'small', label: 'Small' }
]
},
{
name: 'Table Scroll',
formControlName: 'tableScroll',
listOfOption: [
{ value: 'unset', label: 'Unset' },
{ value: 'scroll', label: 'Scroll' },
{ value: 'fixed', label: 'Fixed' }
]
},
{
name: 'Table Layout',
formControlName: 'tableLayout',
listOfOption: [
{ value: 'auto', label: 'Auto' },
{ value: 'fixed', label: 'Fixed' }
]
},
{
name: 'Pagination Position',
formControlName: 'position',
listOfOption: [
{ value: 'top', label: 'Top' },
{ value: 'bottom', label: 'Bottom' },
{ value: 'both', label: 'Both' }
]
}
];
currentPageDataChange($event: ItemData[]): 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();
}
generateData(): ItemData[] {
const data = [];
for (let i = 1; i <= 100; i++) {
data.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
});
}
return data;
}
constructor(private formBuilder: FormBuilder) {}
ngOnInit(): void {
this.settingForm = this.formBuilder.group({
bordered: false,
loading: false,
pagination: true,
sizeChanger: false,
title: true,
header: true,
footer: true,
expandable: true,
checkbox: true,
fixHeader: false,
noResult: false,
ellipsis: false,
simple: false,
size: 'small',
tableScroll: 'unset',
tableLayout: 'auto',
position: 'bottom'
});
this.settingValue = this.settingForm.value;
this.settingForm.valueChanges.subscribe(value => (this.settingValue = value));
this.settingForm.get('tableScroll')!.valueChanges.subscribe(scroll => {
this.fixedColumn = scroll === 'fixed';
this.scrollX = scroll === 'scroll' || scroll === 'fixed' ? '100vw' : null;
});
this.settingForm.get('fixHeader')!.valueChanges.subscribe(fixed => {
this.scrollY = fixed ? '240px' : null;
});
this.settingForm.get('noResult')!.valueChanges.subscribe(empty => {
if (empty) {
this.listOfData = [];
} else {
this.listOfData = this.generateData();
}
});
this.listOfData = this.generateData();
}
}
API
nz-tablecomponent
参数 | 说明 | 类型 | 默认值 | 全局配置 |
---|---|---|---|---|
[nzData] | 数据数组 | any[] | - | |
[nzFrontPagination] | 是否在前端对数据进行分页,如果在服务器分页数据或者需要在前端显示全部数据时传入 false | boolean | true | |
[nzTotal] | 当前总数据,在服务器渲染时需要传入 | number | - | |
[nzPageIndex] | 当前页码,可双向绑定 | number | - | |
[nzPageSize] | 每页展示多少数据,可双向绑定 | number | - | |
[nzShowPagination] | 是否显示分页器 | boolean | true | |
[nzPaginationPosition] | 指定分页显示的位置 | ‘top’ | ‘bottom’ | ‘both’ | bottom | |
[nzBordered] | 是否展示外边框和列边框 | boolean | false | ✅ |
[nzOutBordered] | 是否显示外边框 | boolean | false | - |
[nzWidthConfig] | 表头分组时指定每列宽度,与 th 的 [nzWidth] 不可混用 | string[] | [] | |
[nzSize] | 正常或迷你类型 | ‘middle’ | ‘small’ | ‘default’ | ‘default’ | ✅ |
[nzLoading] | 页面是否加载中 | boolean | false | |
[nzLoadingIndicator] | 加载指示符 | TemplateRef<void> | - | ✅ |
[nzLoadingDelay] | 延迟显示加载效果的时间(防止闪烁) | number | 0 | |
[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] | 是否可以快速跳转至某页 | boolean | false | ✅ |
[nzShowSizeChanger] | 是否可以改变 nzPageSize | boolean | false | ✅ |
[nzShowTotal] | 用于显示数据总量和当前数据范围,用法参照 Pagination 组件 | TemplateRef<{ $implicit: number, range: [ number, number ] }> | - | |
[nzItemRender] | 用于自定义页码的结构,用法参照 Pagination 组件 | TemplateRef<{ $implicit: ‘page’ | ‘prev’ | ‘next’, page: number }> | - | |
[nzHideOnSinglePage] | 只有一页时是否隐藏分页器 | boolean | false | ✅ |
[nzSimple] | 当添加该属性时,显示为简单分页 | boolean | - | ✅ |
[nzVirtualItemSize] | 虚拟滚动时每一列的高度,与 cdk itemSize 相同 | number | 0 | |
[nzVirtualMaxBufferPx] | 缓冲区最大像素高度,与 cdk maxBufferPx 相同 | number | 200 | |
[nzVirtualMinBufferPx] | 缓冲区最小像素高度,低于该值时将加载新结构,与 cdk minBufferPx 相同 | number | 100 | |
[nzVirtualForTrackBy] | 虚拟滚动数据 TrackByFunction 函数 | TrackByFunction<T> | - | |
(nzPageIndexChange) | 当前页码改变时的回调函数 | EventEmitter<number> | - | |
(nzPageSizeChange) | 页数改变时的回调函数 | EventEmitter<number> | - | |
(nzCurrentPageDataChange) | 当前页面展示数据改变的回调函数 | EventEmitter<any[]> | - | |
(nzQueryParams) | 当服务端分页、筛选、排序时,用于获得参数,具体见示例 | EventEmitter<NzTableQueryParams> | - |
th
勾选属性
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
[nzShowCheckbox] | 是否添加checkbox | boolean | - |
[nzDisabled] | checkbox 是否禁用 | boolean | - |
[nzIndeterminate] | checkbox indeterminate 状态 | boolean | - |
[nzChecked] | checkbox 是否被选中,可双向绑定 | boolean | - |
(nzCheckedChange) | 选中的回调 | EventEmitter<boolean> | - |
下拉选择属性
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
[nzShowRowSelection] | 是否显示下拉选择 | boolean | - |
[nzSelections] | 下拉选择的内容 text 及回调函数 onSelect | Array<{ text: string, onSelect: any }> | - |
排序属性
参数 | 说明 | 类型 | 默认值 | |
---|---|---|---|---|
[nzShowSort] | 是否显示排序 | boolean | - | |
[nzSortFn] | 排序函数,前端排序使用一个函数(参考 Array.sort 的 compareFunction),服务端排序时传入 true | ((a: any, b: any, sortOrder?: string) => number)</td><td>boolean | - | |
[nzSortDirections] | 支持的排序方式,取值为 ‘ascend’ , ‘descend’ , null | Array<’ascend’ | ‘descend’ | null> | [‘ascend’, ‘descend’, null] | |
[nzSortOrder] | 当前排序状态,可双向绑定 | ‘descend’ | ‘ascend’ | null | null | |
(nzSortOrderChange) | 排序状态改变回调 | EventEmitter<’descend’ | ‘ascend’ | null> | - |
过滤属性
参数 | 说明 | 类型 | 默认值 | |
---|---|---|---|---|
[nzShowFilter] | 是否显示过滤 | boolean | - | |
[nzFilterFn] | 前端排序时,确定筛选的运行函数,服务端排序时,传入 true | ((value: any, data: any) => boolean;)</td><td>boolean | - | |
[nzFilters] | 过滤器内容, 显示数据 text ,回调函数传出 value ,设置 byDefault 以默认应用过滤规则 | Array<{ text: string; value: any; byDefault?: boolean }> | - | |
[nzFilterMultiple] | 是否为多选过滤器 | boolean | true | |
(nzFilterChange) | 过滤器内容选择的 value 数据回调 | EventEmitter<any[] | any> | - |
样式属性
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
[nzWidth] | 指定该列宽度,表头未分组时可用 | string | - |
[nzLeft] | 左侧距离,用于固定左侧列,当为 true 时自动计算,为 false 时停止固定 | string | boolean | false |
[nzRight] | 右侧距离,用于固定右侧列,当为 true 时自动计算,为 false 时停止固定 | string | boolean | false |
[nzAlign] | 设置列内容的对齐方式 | ‘left’ | ‘right’ | ‘center’ | - |
[nzBreakWord] | 是否折行显示 | boolean | false |
[nzEllipsis] | 超过宽度将自动省略,暂不支持和排序筛选一起使用。仅当表格布局将为 nzTableLayout=”fixed” 时可用 | boolean | false |
[colSpan] | 每单元格中扩展列的数量 | number | null |
[rowSpan] | 每单元格中扩展行的数量 | number | null |
其他
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
[nzColumnKey] | 当前列的key,用于服务端筛选和排序使用 | string | - |
td
勾选属性
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
[nzShowCheckbox] | 是否添加checkbox | boolean | - |
[nzDisabled] | checkbox 是否禁用 | boolean | - |
[nzIndeterminate] | checkbox indeterminate 状态 | boolean | - |
[nzChecked] | checkbox 是否被选中,可双向绑定 | boolean | - |
(nzCheckedChange) | 选中的回调 | EventEmitter<boolean> | - |
展开属性
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
[nzShowExpand] | 是否显示展开按钮 | boolean | - |
[nzExpand] | 当前展开按钮状态,可双向绑定 | boolean | - |
(nzExpandChange) | 当前展开按钮状态改变回调函数 | EventEmitter<boolean> | - |
样式属性
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
[nzLeft] | 左侧距离,用于固定左侧列,当为 true 时自动计算,为 false 时停止固定 | string | boolean | false |
[nzRight] | 右侧距离,用于固定右侧列,当为 true 时自动计算,为 false 时停止固定 | string | boolean | false |
[nzAlign] | 设置列内容的对齐方式 | ‘left’ | ‘right’ | ‘center’ | - |
[nzBreakWord] | 是否折行显示 | boolean | false |
[nzEllipsis] | 超过宽度将自动省略,暂不支持和排序筛选一起使用。仅当表格布局将为 nzTableLayout=”fixed” 时可用 | boolean | false |
其他
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
[nzIndentSize] | 展示树形数据时,每层缩进的宽度,以 px 为单位 | number | - |
tr
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
[nzExpand] | 当前列是否展开,与 td 上的 nzExpand 属性配合使用 | boolean | - |
nz-filter-triggercomponent
用于自定义筛选功能
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
[nzDropdownMenu] | Dropdown 下拉菜单组件 | NzDropdownMenuComponent | - |
[nzVisible] | 菜单是否显示,可双向绑定 | boolean | - |
[nzActive] | 是否激活选中图标效果 | boolean | false |
(nzVisibleChange) | 菜单显示状态改变时调用,参数为 nzVisible | EventEmitter<boolean> | - |
[nz-virtual-scroll]directive
虚拟滚动时配合 ng-template
使用, 格式为: TemplateRef<{ $implicit: any, index: number }>
.
注意
为了获得更好的性能,NG-ZORRO 所有组件都运行在 OnPush 模式下,这意味着对 @Input()
数据的 mutate 将不会生效,请使用 immutable 方式操作数组或者对象。
// 增加数据
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);
开发者也可以使用 immer 获得更好的操作体验