Transfer穿梭框

    用直观的方式在两栏中移动元素,完成选择行为。

    选择一个或以上的选项后,点击对应的方向键,可以把选中的选项移动到另一栏。 其中,左边一栏为 ,右边一栏为 target,API 的设计也反映了这两个概念。

    基本用法

    最基本的用法,展示了 nzDataSource 每行的渲染函数 nzRender 以及回调函数 nzChangenzSelectChange 的用法。

    1. import { Component, OnInit } from '@angular/core';
    2. import { TransferItem } from 'ng-zorro-antd/transfer';
    3. @Component({
    4. selector: 'nz-demo-transfer-basic',
    5. template: `
    6. <nz-transfer
    7. [nzDataSource]="list"
    8. [nzDisabled]="disabled"
    9. [nzTitles]="['Source', 'Target']"
    10. (nzSelectChange)="select($event)"
    11. [nzSelectedKeys]="['0', '2']"
    12. (nzChange)="change($event)"
    13. >
    14. </nz-transfer>
    15. <div style="margin-top: 8px;">
    16. <nz-switch [(ngModel)]="disabled" nzCheckedChildren="disabled" nzUnCheckedChildren="disabled"></nz-switch>
    17. <div></div>
    18. </div>
    19. `
    20. })
    21. export class NzDemoTransferBasicComponent implements OnInit {
    22. list: TransferItem[] = [];
    23. disabled = false;
    24. ngOnInit(): void {
    25. for (let i = 0; i < 20; i++) {
    26. this.list.push({
    27. key: i.toString(),
    28. title: `content${i + 1}`,
    29. disabled: i % 3 < 1
    30. });
    31. }
    32. [2, 3].forEach(idx => (this.list[idx].direction = 'right'));
    33. }
    34. select(ret: {}): void {
    35. console.log('nzSelectChange', ret);
    36. }
    37. change(ret: {}): void {
    38. console.log('nzChange', ret);
    39. }
    40. }

    Transfer穿梭框 - 图4

    带搜索框

    高级用法

    穿梭框高级用法,可配置操作文案,可定制宽高,可对底部进行自定义渲染。

    1. import { Component, OnInit } from '@angular/core';
    2. import { NzMessageService } from 'ng-zorro-antd/message';
    3. import { TransferItem } from 'ng-zorro-antd/transfer';
    4. @Component({
    5. selector: 'nz-demo-transfer-advanced',
    6. template: `
    7. <nz-transfer
    8. [nzDataSource]="list"
    9. nzShowSearch
    10. [nzOperations]="['to right', 'to left']"
    11. [nzListStyle]="{ 'width.px': 250, 'height.px': 300 }"
    12. [nzRender]="render"
    13. [nzFooter]="footer"
    14. (nzSelectChange)="select($event)"
    15. (nzChange)="change($event)"
    16. >
    17. <ng-template #render let-item> {{ item.title }}-{{ item.description }} </ng-template>
    18. <ng-template #footer let-direction>
    19. <button nz-button (click)="reload(direction)" [nzSize]="'small'" style="float: right; margin: 5px;">
    20. reload
    21. </button>
    22. </ng-template>
    23. </nz-transfer>
    24. `
    25. })
    26. export class NzDemoTransferAdvancedComponent implements OnInit {
    27. list: TransferItem[] = [];
    28. ngOnInit(): void {
    29. this.getData();
    30. }
    31. getData(): void {
    32. const ret: TransferItem[] = [];
    33. for (let i = 0; i < 20; i++) {
    34. ret.push({
    35. key: i.toString(),
    36. title: `content${i + 1}`,
    37. description: `description of content${i + 1}`,
    38. direction: Math.random() * 2 > 1 ? 'right' : undefined
    39. });
    40. }
    41. this.list = ret;
    42. }
    43. reload(direction: string): void {
    44. this.getData();
    45. this.msg.success(`your clicked ${direction}!`);
    46. }
    47. select(ret: {}): void {
    48. console.log('nzSelectChange', ret);
    49. }
    50. change(ret: {}): void {
    51. console.log('nzChange', ret);
    52. }
    53. }

    Transfer穿梭框 - 图6

    自定义渲染行数据

    自定义渲染每一个 Transfer Item,可用于渲染复杂数据。

    利用 nzCanMove 允许在穿梭过程中二次校验;示例默认向右移时强制选中的第一项不可穿梭。

    1. import { Component, OnInit } from '@angular/core';
    2. import { TransferCanMove, TransferItem } from 'ng-zorro-antd/transfer';
    3. import { Observable, of } from 'rxjs';
    4. import { delay } from 'rxjs/operators';
    5. @Component({
    6. selector: 'nz-demo-transfer-can-move',
    7. template: `
    8. <nz-transfer [nzDataSource]="list" [nzCanMove]="canMove" (nzSelectChange)="select($event)" (nzChange)="change($event)"> </nz-transfer>
    9. `
    10. })
    11. export class NzDemoTransferCanMoveComponent implements OnInit {
    12. list: TransferItem[] = [];
    13. ngOnInit(): void {
    14. for (let i = 0; i < 20; i++) {
    15. this.list.push({
    16. key: i.toString(),
    17. title: `content${i + 1}`,
    18. disabled: i % 3 < 1
    19. });
    20. }
    21. [2, 3].forEach(idx => (this.list[idx].direction = 'right'));
    22. }
    23. canMove(arg: TransferCanMove): Observable<TransferItem[]> {
    24. if (arg.direction === 'right' && arg.list.length > 0) {
    25. arg.list.splice(0, 1);
    26. }
    27. // or
    28. // if (arg.direction === 'right' && arg.list.length > 0) delete arg.list[0];
    29. return of(arg.list).pipe(delay(1000));
    30. }
    31. select(ret: {}): void {
    32. console.log('nzSelectChange', ret);
    33. }
    34. change(ret: {}): void {
    35. console.log('nzChange', ret);
    36. }
    37. }

    Transfer穿梭框 - 图8

    表格穿梭框

    使用 Table 组件作为自定义渲染列表。

    树穿梭框

    使用 Tree 组件作为自定义渲染列表。

    1. import { ChangeDetectionStrategy, Component, ViewChild } from '@angular/core';
    2. import { NzTreeNode, NzTreeNodeOptions } from 'ng-zorro-antd/core/tree';
    3. import { TransferChange } from 'ng-zorro-antd/transfer';
    4. import { NzTreeComponent } from 'ng-zorro-antd/tree';
    5. @Component({
    6. selector: 'nz-demo-transfer-tree-transfer',
    7. <nz-transfer [nzDataSource]="list" [nzShowSelectAll]="false" [nzRenderList]="[leftRenderList, null]" (nzChange)="change($event)">
    8. <ng-template #leftRenderList let-items let-onItemSelectAll="onItemSelectAll" let-onItemSelect="onItemSelect">
    9. <nz-tree #tree [nzData]="treeData" nzExpandAll nzBlockNode>
    10. <ng-template #nzTreeTemplate let-node>
    11. <span
    12. class="ant-tree-checkbox"
    13. [class.ant-tree-checkbox-disabled]="node.isDisabled"
    14. [class.ant-tree-checkbox-checked]="node.isChecked"
    15. (click)="checkBoxChange(node, onItemSelect)"
    16. >
    17. <span class="ant-tree-checkbox-inner"></span>
    18. </span>
    19. <span (click)="checkBoxChange(node, onItemSelect)" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open">{{
    20. node.title
    21. }}</span>
    22. </ng-template>
    23. </nz-tree>
    24. </ng-template>
    25. </nz-transfer>
    26. `,
    27. changeDetection: ChangeDetectionStrategy.OnPush
    28. })
    29. export class NzDemoTransferTreeTransferComponent {
    30. @ViewChild('tree', { static: true }) tree!: NzTreeComponent;
    31. list: NzTreeNodeOptions[] = [
    32. { key: '1', id: 1, parentid: 0, title: 'parent 1' },
    33. { key: '2', id: 2, parentid: 1, title: 'leaf 1-1', disabled: true, isLeaf: true },
    34. { key: '3', id: 3, parentid: 1, title: 'leaf 1-2', isLeaf: true }
    35. ];
    36. treeData = this.generateTree(this.list);
    37. checkedNodeList: NzTreeNode[] = [];
    38. private generateTree(arr: NzTreeNodeOptions[]): NzTreeNodeOptions[] {
    39. const tree: NzTreeNodeOptions[] = [];
    40. // tslint:disable-next-line:no-any
    41. const mappedArr: any = {};
    42. let arrElem: NzTreeNodeOptions;
    43. let mappedElem: NzTreeNodeOptions;
    44. for (let i = 0, len = arr.length; i < len; i++) {
    45. arrElem = arr[i];
    46. mappedArr[arrElem.id] = { ...arrElem };
    47. mappedArr[arrElem.id].children = [];
    48. }
    49. for (const id in mappedArr) {
    50. if (mappedArr.hasOwnProperty(id)) {
    51. mappedElem = mappedArr[id];
    52. if (mappedElem.parentid) {
    53. mappedArr[mappedElem.parentid].children.push(mappedElem);
    54. } else {
    55. tree.push(mappedElem);
    56. }
    57. }
    58. }
    59. return tree;
    60. checkBoxChange(node: NzTreeNode, onItemSelect: (item: NzTreeNodeOptions) => void): void {
    61. if (node.isDisabled) {
    62. return;
    63. }
    64. node.isChecked = !node.isChecked;
    65. if (node.isChecked) {
    66. this.checkedNodeList.push(node);
    67. } else {
    68. const idx = this.checkedNodeList.indexOf(node);
    69. if (idx !== -1) {
    70. this.checkedNodeList.splice(idx, 1);
    71. }
    72. }
    73. const item = this.list.find(w => w.id === node.origin.id);
    74. onItemSelect(item!);
    75. }
    76. change(ret: TransferChange): void {
    77. const isDisabled = ret.to === 'right';
    78. this.checkedNodeList.forEach(node => {
    79. node.isDisabled = isDisabled;
    80. node.isChecked = isDisabled;
    81. });
    82. }

    TransferItem

    参数说明类型默认值
    title标题,用于显示及搜索关键字判断string-
    direction指定数据方向,若指定 right 为右栏,其他情况为左栏‘left’ | ‘right’-
    disabled指定checkbox为不可用状态booleanfalse
    checked指定checkbox为选中状态booleanfalse

    TransferCanMove

    TransferChange

    参数说明类型默认值
    from数据方向‘left’ | ‘right’-
    to数据方向‘left’ | ‘right’-
    list数据源TransferItem[][]

    TransferSearchChange

    nzRenderList

    参数说明类型默认值
    direction渲染列表的方向‘left’ | ‘right’-
    disabled是否禁用列表boolean-
    items过滤后的数据TransferItem[]-
    onItemSelect勾选条目(item: TransferItem) => void-
    onItemSelectAll勾选一组条目-