List列表
最基础的列表展示,可承载文字、列表、图片、段落,常用于后台数据展示页面。
想要了解更多关于单独引入组件的内容,可以在快速上手页面进行查看。
列表拥有大、中、小三种尺寸。
通过设置 为 large
small
分别把按钮设为大、小尺寸。若不设置 size
,则尺寸为中。
可通过设置 nzHeader
和 nzFooter
,来自定义列表头部和尾部。
import { Component } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd/message';
@Component({
selector: 'nz-demo-list-simple',
template: `
<h3 [ngStyle]="{ 'margin-bottom.px': 16 }">Default Size</h3>
<nz-list [nzDataSource]="data" nzBordered [nzHeader]="'Header'" [nzFooter]="'Footer'" [nzRenderItem]="defaultItem">
<ng-template #defaultItem let-item>
<nz-list-item>
<span class="ant-typography"><mark>[ITEM]</mark></span>
{{ item }}
</nz-list-item>
</ng-template>
</nz-list>
<h3 [ngStyle]="{ margin: '16px 0' }">Small Size</h3>
<nz-list
[nzDataSource]="data"
nzBordered
nzSize="small"
[nzHeader]="'Header'"
[nzFooter]="'Footer'"
[nzRenderItem]="smallItem"
>
<ng-template #smallItem let-item><nz-list-item [nzContent]="item"></nz-list-item></ng-template>
</nz-list>
<h3 [ngStyle]="{ margin: '16px 0' }">Large Size</h3>
<ul
nz-list
[nzDataSource]="data"
nzBordered
nzSize="large"
[nzHeader]="'Header'"
[nzFooter]="'Footer'"
[nzRenderItem]="largeItem"
>
<ng-template #largeItem let-item>
<li nz-list-item [nzActions]="[opAction]" [nzContent]="item" nzNoFlex></li>
<ng-template #opAction><a (click)="msg.info('edit')">edit</a></ng-template>
</ng-template>
</ul>
`
})
export class NzDemoListSimpleComponent {
data = [
'Racing car sprays burning fuel into crowd.',
'Japanese princess to wed commoner.',
'Australian walks 100km after outback crash.',
'Man charged over missing wedding girl.',
'Los Angeles battles huge wildfires.'
];
constructor(public msg: NzMessageService) {}
}
基础列表。
可通过 loadMore
属性实现加载更多功能。
// tslint:disable:no-any
import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd/message';
const count = 5;
const fakeDataUrl = 'https://randomuser.me/api/?results=5&inc=name,gender,email,nat&noinfo';
@Component({
selector: 'nz-demo-list-loadmore',
template: `
<nz-list
class="demo-loadmore-list"
[nzDataSource]="list"
[nzItemLayout]="'horizontal'"
[nzLoading]="initLoading"
[nzRenderItem]="item"
[nzLoadMore]="loadMore"
>
<ng-template #item let-item>
<nz-list-item
[nzContent]="item.loading ? '' : 'content'"
[nzActions]="item.loading ? [] : [editAction, moreAction]"
>
<nz-skeleton [nzAvatar]="true" [nzActive]="true" [nzTitle]="false" [nzLoading]="item.loading">
<ng-template #editAction><a (click)="edit(item)">edit</a></ng-template>
<ng-template #moreAction><a (click)="edit(item)">more</a></ng-template>
<nz-list-item-meta
[nzTitle]="nzTitle"
nzAvatar="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
nzDescription="Ant Design, a design language for background applications, is refined by Ant UED Team"
>
<ng-template #nzTitle>
</ng-template>
</nz-list-item-meta>
</nz-skeleton>
</nz-list-item>
</ng-template>
<ng-template #loadMore>
<div class="loadmore">
<button nz-button *ngIf="!loadingMore" (click)="onLoadMore()">loading more</button>
</div>
</ng-template>
</nz-list>
`,
styles: [
`
.demo-loadmore-list {
min-height: 350px;
}
.loadmore {
text-align: center;
margin-top: 12px;
height: 32px;
line-height: 32px;
}
`
]
})
initLoading = true; // bug
loadingMore = false;
data: any[] = [];
list: Array<{ loading: boolean; name: any }> = [];
constructor(private http: HttpClient, private msg: NzMessageService) {}
ngOnInit(): void {
this.getData((res: any) => {
this.data = res.results;
this.list = res.results;
this.initLoading = false;
});
}
getData(callback: (res: any) => void): void {
this.http.get(fakeDataUrl).subscribe((res: any) => callback(res));
}
onLoadMore(): void {
this.loadingMore = true;
this.list = this.data.concat([...Array(count)].fill({}).map(() => ({ loading: true, name: {} })));
this.http.get(fakeDataUrl).subscribe((res: any) => {
this.data = this.data.concat(res.results);
this.list = [...this.data];
this.loadingMore = false;
});
}
edit(item: any): void {
this.msg.success(item.email);
}
}
通过设置 nzItemLayout
属性为 vertical
可实现竖排列表样式。
可以通过设置 nz-list
的 grid
属性来实现栅格列表,column
可设置期望显示的列数。
import { Component } from '@angular/core';
@Component({
selector: 'nz-demo-list-grid',
template: `
<nz-list [nzDataSource]="data" [nzRenderItem]="item" [nzGrid]="{ gutter: 16, span: 6 }">
<ng-template #item let-item>
<nz-list-item [nzContent]="nzContent">
<ng-template #nzContent>
<nz-card [nzTitle]="item.title">
Card content
</nz-card>
</ng-template>
</nz-list-item>
</ng-template>
</nz-list>
`
})
export class NzDemoListGridComponent {
data = [
{
title: 'Title 1'
},
{
title: 'Title 2'
},
{
title: 'Title 3'
},
{
title: 'Title 4'
}
];
}
响应式的栅格列表。尺寸与 Layout Grid 保持一致。
结合 cdk-virtual-scroll 实现滚动加载无限长列表,带有虚拟化 virtualization 功能,能够提高数据量大时候长列表的性能。
Virtualized
是在大数据列表中应用的一种技术,主要是为了减少不可见区域不必要的渲染从而提高性能,特别是数据量在成千上万条效果尤为明显。
// tslint:disable:no-any
import { HttpClient } from '@angular/common/http';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
@Component({
selector: 'nz-demo-list-infinite-load',
template: `
<div>
<cdk-virtual-scroll-viewport itemSize="73" class="demo-infinite-container">
<nz-list>
<nz-list-item *cdkVirtualFor="let item of ds">
<nz-skeleton *ngIf="!item" [nzAvatar]="true" [nzParagraph]="{ rows: 1 }"></nz-skeleton>
<nz-list-item-meta
*ngIf="item"
[nzTitle]="nzTitle"
nzAvatar="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
[nzDescription]="item.email"
>
<ng-template #nzTitle>
<a href="https://ng.ant.design">{{ item.name.last }}</a>
</ng-template>
</nz-list-item-meta>
</nz-list-item>
</nz-list>
</cdk-virtual-scroll-viewport>
</div>
`,
styles: [
`
.demo-infinite-container {
height: 300px;
border: 1px solid #e8e8e8;
border-radius: 4px;
}
nz-list {
padding: 24px;
}
`
],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class NzDemoListInfiniteLoadComponent {
ds = new MyDataSource(this.http);
}
class MyDataSource extends DataSource<string | undefined> {
private length = 100000;
private pageSize = 10;
private cachedData = Array.from<any>({ length: this.length });
private fetchedPages = new Set<number>();
private dataStream = new BehaviorSubject<any[]>(this.cachedData);
private subscription = new Subscription();
constructor(private http: HttpClient) {
super();
}
connect(collectionViewer: CollectionViewer): Observable<any[]> {
this.subscription.add(
collectionViewer.viewChange.subscribe(range => {
const startPage = this.getPageForIndex(range.start);
const endPage = this.getPageForIndex(range.end - 1);
for (let i = startPage; i <= endPage; i++) {
this.fetchPage(i);
}
})
);
return this.dataStream;
}
disconnect(): void {
this.subscription.unsubscribe();
}
private getPageForIndex(index: number): number {
return Math.floor(index / this.pageSize);
}
private fetchPage(page: number): void {
if (this.fetchedPages.has(page)) {
return;
}
this.fetchedPages.add(page);
this.http
.get(`https://randomuser.me/api/?results=${this.pageSize}&inc=name,gender,email,nat&noinfo`)
.subscribe((res: any) => {
this.cachedData.splice(page * this.pageSize, this.pageSize, ...res.results);
this.dataStream.next(this.cachedData);
});
}
}