Modal对话框

    需要用户处理事务,又不希望跳转页面以致打断工作流程时,可以使用 在当前页面正中打开一个浮层,承载相应的操作。

    另外当需要一个简洁的确认框询问用户时,可以使用精心封装好的 NzModalService.confirm() 等方法。

    推荐使用加载Component的方式弹出Modal,这样弹出层的Component逻辑可以与外层Component完全隔离,并且做到可以随时复用,

    在弹出层Component中可以通过依赖注入NzModalRef方式直接获取模态框的组件实例,用于控制在弹出层组件中控制模态框行为。

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

    第一个对话框。

    1. import { Component } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-modal-basic',
    4. template: `
    5. <button nz-button [nzType]="'primary'" (click)="showModal()"><span>Show Modal</span></button>
    6. <nz-modal [(nzVisible)]="isVisible" nzTitle="The first Modal" (nzOnCancel)="handleCancel()" (nzOnOk)="handleOk()">
    7. <p>Content one</p>
    8. <p>Content two</p>
    9. <p>Content three</p>
    10. </nz-modal>
    11. `
    12. })
    13. export class NzDemoModalBasicComponent {
    14. isVisible = false;
    15. constructor() {}
    16. showModal(): void {
    17. this.isVisible = true;
    18. }
    19. handleOk(): void {
    20. console.log('Button ok clicked!');
    21. this.isVisible = false;
    22. }
    23. handleCancel(): void {
    24. console.log('Button cancel clicked!');
    25. this.isVisible = false;
    26. }
    27. }

    Modal对话框 - 图2

    自定义页脚

    更复杂的例子,自定义了页脚的按钮,点击提交后进入 loading 状态,完成后关闭。

    不需要默认确定取消按钮时,你可以把 nzFooter 设为 null

    1. import { Component } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-modal-footer',
    4. template: `
    5. <button nz-button nzType="primary" (click)="showModal()">
    6. <span>Show Modal</span>
    7. </button>
    8. <nz-modal
    9. [(nzVisible)]="isVisible"
    10. [nzTitle]="modalTitle"
    11. [nzContent]="modalContent"
    12. [nzFooter]="modalFooter"
    13. (nzOnCancel)="handleCancel()"
    14. >
    15. <ng-template #modalTitle>
    16. Custom Modal Title
    17. </ng-template>
    18. <ng-template #modalContent>
    19. <p>Modal Content</p>
    20. <p>Modal Content</p>
    21. <p>Modal Content</p>
    22. <p>Modal Content</p>
    23. <p>Modal Content</p>
    24. </ng-template>
    25. <ng-template #modalFooter>
    26. <span>Modal Footer: </span>
    27. <button nz-button nzType="default" (click)="handleCancel()">Custom Callback</button>
    28. <button nz-button nzType="primary" (click)="handleOk()" [nzLoading]="isConfirmLoading">Custom Submit</button>
    29. </ng-template>
    30. </nz-modal>
    31. `
    32. })
    33. export class NzDemoModalFooterComponent {
    34. isVisible = false;
    35. isConfirmLoading = false;
    36. constructor() {}
    37. showModal(): void {
    38. this.isVisible = true;
    39. }
    40. handleOk(): void {
    41. this.isConfirmLoading = true;
    42. setTimeout(() => {
    43. this.isVisible = false;
    44. this.isConfirmLoading = false;
    45. }, 3000);
    46. }
    47. handleCancel(): void {
    48. this.isVisible = false;
    49. }
    50. }

    使用 NzModalService.confirm() 可以快捷地弹出确认框。

    1. import { Component } from '@angular/core';
    2. import { NzModalService } from 'ng-zorro-antd/modal';
    3. @Component({
    4. selector: 'nz-demo-modal-confirm',
    5. template: `
    6. <button nz-button nzType="info" (click)="showConfirm()">Confirm</button>
    7. <button nz-button nzType="dashed" (click)="showDeleteConfirm()">Delete</button>
    8. `,
    9. styles: [
    10. `
    11. button {
    12. margin-right: 8px;
    13. }
    14. `
    15. ]
    16. })
    17. export class NzDemoModalConfirmComponent {
    18. constructor(private modalService: NzModalService) {}
    19. showConfirm(): void {
    20. this.modalService.confirm({
    21. nzTitle: '<i>Do you Want to delete these items?</i>',
    22. nzContent: '<b>Some descriptions</b>',
    23. nzOnOk: () => console.log('OK')
    24. });
    25. }
    26. showDeleteConfirm(): void {
    27. this.modalService.confirm({
    28. nzTitle: 'Are you sure delete this task?',
    29. nzContent: '<b style="color: red;">Some descriptions</b>',
    30. nzOkText: 'Yes',
    31. nzOkType: 'danger',
    32. nzOnOk: () => console.log('OK'),
    33. nzCancelText: 'No',
    34. nzOnCancel: () => console.log('Cancel')
    35. });
    36. }
    37. }

    Modal对话框 - 图4

    信息提示

    各种类型的信息提示,只提供一个按钮用于关闭。

    1. import { Component } from '@angular/core';
    2. import { NzModalService } from 'ng-zorro-antd/modal';
    3. @Component({
    4. selector: 'nz-demo-modal-info',
    5. template: `
    6. <button nz-button (click)="info()">Info</button>
    7. <button nz-button (click)="success()">Success</button>
    8. <button nz-button (click)="error()">Error</button>
    9. <button nz-button (click)="warning()">Warning</button>
    10. `,
    11. styles: [
    12. `
    13. button {
    14. margin-right: 8px;
    15. }
    16. `
    17. ]
    18. })
    19. export class NzDemoModalInfoComponent {
    20. constructor(private modalService: NzModalService) {}
    21. info(): void {
    22. this.modalService.info({
    23. nzTitle: 'This is a notification message',
    24. nzContent: '<p>some messages...some messages...</p><p>some messages...some messages...</p>',
    25. nzOnOk: () => console.log('Info OK')
    26. });
    27. }
    28. success(): void {
    29. this.modalService.success({
    30. nzTitle: 'This is a success message',
    31. nzContent: 'some messages...some messages...'
    32. });
    33. }
    34. error(): void {
    35. this.modalService.error({
    36. nzTitle: 'This is an error message',
    37. nzContent: 'some messages...some messages...'
    38. });
    39. }
    40. warning(): void {
    41. this.modalService.warning({
    42. nzTitle: 'This is an warning message',
    43. nzContent: 'some messages...some messages...'
    44. });
    45. }
    46. }

    手动关闭modal。

    服务方式创建

    Modal的service用法,示例中演示了用户自定义模板、自定义component、以及注入模态框实例的方法。

    1. /* entryComponents: NzModalCustomComponent */
    2. import { Component, Input, TemplateRef } from '@angular/core';
    3. import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal';
    4. @Component({
    5. selector: 'nz-demo-modal-service',
    6. template: `
    7. <button nz-button nzType="primary" (click)="createModal()">
    8. <span>String</span>
    9. </button>
    10. <button nz-button nzType="primary" (click)="createTplModal(tplTitle, tplContent, tplFooter)">
    11. <span>Template</span>
    12. </button>
    13. <ng-template #tplTitle>
    14. <span>Title Template</span>
    15. </ng-template>
    16. <ng-template #tplContent>
    17. <p>some contents...</p>
    18. <p>some contents...</p>
    19. <p>some contents...</p>
    20. <p>some contents...</p>
    21. <p>some contents...</p>
    22. <ng-template #tplFooter>
    23. <button nz-button nzType="primary" (click)="destroyTplModal()" [nzLoading]="tplModalButtonLoading">
    24. Close after submit
    25. </button>
    26. </ng-template>
    27. <br /><br />
    28. <button nz-button nzType="primary" (click)="createComponentModal()">
    29. <span>Use Component</span>
    30. </button>
    31. <button nz-button nzType="primary" (click)="createCustomButtonModal()">Custom Button</button>
    32. <br /><br />
    33. <button nz-button nzType="primary" (click)="openAndCloseAll()">Open more modals then close all after 2s</button>
    34. <nz-modal [(nzVisible)]="htmlModalVisible" nzMask="false" nzZIndex="1001" nzTitle="Non-service html modal"
    35. >This is a non-service html modal</nz-modal
    36. >
    37. `,
    38. styles: [
    39. `
    40. button {
    41. margin-right: 8px;
    42. }
    43. ]
    44. })
    45. export class NzDemoModalServiceComponent {
    46. tplModal: NzModalRef;
    47. tplModalButtonLoading = false;
    48. htmlModalVisible = false;
    49. disabled = false;
    50. constructor(private modalService: NzModalService) {}
    51. createModal(): void {
    52. this.modalService.create({
    53. nzTitle: 'Modal Title',
    54. nzContent: 'string, will close after 1 sec',
    55. nzClosable: false,
    56. nzOnOk: () => new Promise(resolve => setTimeout(resolve, 1000))
    57. });
    58. }
    59. createTplModal(tplTitle: TemplateRef<{}>, tplContent: TemplateRef<{}>, tplFooter: TemplateRef<{}>): void {
    60. this.tplModal = this.modalService.create({
    61. nzTitle: tplTitle,
    62. nzContent: tplContent,
    63. nzFooter: tplFooter,
    64. nzMaskClosable: false,
    65. nzClosable: false,
    66. nzOnOk: () => console.log('Click ok')
    67. });
    68. }
    69. destroyTplModal(): void {
    70. this.tplModalButtonLoading = true;
    71. setTimeout(() => {
    72. this.tplModalButtonLoading = false;
    73. this.tplModal.destroy();
    74. }, 1000);
    75. }
    76. createComponentModal(): void {
    77. const modal = this.modalService.create({
    78. nzTitle: 'Modal Title',
    79. nzContent: NzModalCustomComponent,
    80. nzComponentParams: {
    81. title: 'title in component',
    82. subtitle: 'component sub title,will be changed after 2 sec'
    83. },
    84. nzFooter: [
    85. {
    86. label: 'change component title from outside',
    87. onClick: componentInstance => {
    88. componentInstance!.title = 'title in inner component is changed';
    89. }
    90. }
    91. ]
    92. });
    93. modal.afterOpen.subscribe(() => console.log('[afterOpen] emitted!'));
    94. // Return a result when closed
    95. modal.afterClose.subscribe(result => console.log('[afterClose] The result is:', result));
    96. // delay until modal instance created
    97. setTimeout(() => {
    98. const instance = modal.getContentComponent();
    99. instance.subtitle = 'sub title is changed';
    100. }, 2000);
    101. }
    102. createCustomButtonModal(): void {
    103. const modal: NzModalRef = this.modalService.create({
    104. nzTitle: 'custom button demo',
    105. nzContent: 'pass array of button config to nzFooter to create multiple buttons',
    106. nzFooter: [
    107. {
    108. label: 'Close',
    109. shape: 'default',
    110. onClick: () => modal.destroy()
    111. },
    112. {
    113. label: 'Confirm',
    114. type: 'primary',
    115. onClick: () =>
    116. this.modalService.confirm({ nzTitle: 'Confirm Modal Title', nzContent: 'Confirm Modal Content' })
    117. },
    118. {
    119. label: 'Change Button Status',
    120. type: 'danger',
    121. loading: false,
    122. onClick(): void {
    123. this.loading = true;
    124. setTimeout(() => (this.loading = false), 1000);
    125. setTimeout(() => {
    126. this.loading = false;
    127. this.disabled = true;
    128. this.label = 'can not be clicked!';
    129. }, 2000);
    130. }
    131. },
    132. {
    133. label: 'async load',
    134. type: 'dashed',
    135. onClick: () => new Promise(resolve => setTimeout(resolve, 2000))
    136. }
    137. ]
    138. });
    139. }
    140. openAndCloseAll(): void {
    141. let pos = 0;
    142. ['create', 'info', 'success', 'error'].forEach(method =>
    143. // @ts-ignore
    144. this.modalService[method]({
    145. nzMask: false,
    146. nzTitle: `Test ${method} title`,
    147. nzContent: `Test content: <b>${method}</b>`,
    148. nzStyle: { position: 'absolute', top: `${pos * 70}px`, left: `${pos++ * 300}px` }
    149. })
    150. );
    151. this.htmlModalVisible = true;
    152. this.modalService.afterAllClose.subscribe(() => console.log('afterAllClose emitted!'));
    153. setTimeout(() => this.modalService.closeAll(), 2000);
    154. }
    155. }
    156. @Component({
    157. selector: 'nz-modal-custom-component',
    158. template: `
    159. <div>
    160. <h2>{{ title }}</h2>
    161. <h4>{{ subtitle }}</h4>
    162. <p>
    163. <span>Get Modal instance in component</span>
    164. <button nz-button [nzType]="'primary'" (click)="destroyModal()">destroy modal in the component</button>
    165. </p>
    166. </div>
    167. `
    168. })
    169. export class NzModalCustomComponent {
    170. @Input() title: string;
    171. @Input() subtitle: string;
    172. constructor(private modal: NzModalRef) {}
    173. destroyModal(): void {
    174. this.modal.destroy({ data: 'this the result data' });
    175. }
    176. }

    Modal对话框 - 图7

    点击确定后异步关闭对话框,例如提交表单。

    1. import { Component } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-modal-async',
    4. template: `
    5. <button nz-button nzType="primary" (click)="showModal()">
    6. <span>Show Modal</span>
    7. </button>
    8. <nz-modal
    9. [(nzVisible)]="isVisible"
    10. nzTitle="Modal Title"
    11. (nzOnCancel)="handleCancel()"
    12. (nzOnOk)="handleOk()"
    13. [nzOkLoading]="isOkLoading"
    14. >
    15. <p>Modal Content</p>
    16. </nz-modal>
    17. `
    18. })
    19. export class NzDemoModalAsyncComponent {
    20. isVisible = false;
    21. isOkLoading = false;
    22. showModal(): void {
    23. this.isVisible = true;
    24. }
    25. handleOk(): void {
    26. this.isOkLoading = true;
    27. setTimeout(() => {
    28. this.isVisible = false;
    29. this.isOkLoading = false;
    30. }, 3000);
    31. }
    32. handleCancel(): void {
    33. this.isVisible = false;
    34. }
    35. }

    自定义页脚(2)

    使用 nzModalFooter 指令自定义了页脚的按钮。

    1. /* entryComponents: NzModalCustomFooterComponent */
    2. import { Component } from '@angular/core';
    3. import { NzModalService, NzModalRef } from 'ng-zorro-antd/modal';
    4. @Component({
    5. selector: 'nz-demo-modal-footer2',
    6. template: `
    7. <button nz-button nzType="primary" (click)="showModal1()">
    8. <span>In Template</span>
    9. </button>
    10. <br />
    11. <br />
    12. <button nz-button nzType="primary" (click)="showModal2()">
    13. <span>In Component</span>
    14. </button>
    15. <nz-modal [(nzVisible)]="isVisible" nzTitle="Custom Modal Title" (nzOnCancel)="handleCancel()">
    16. <div>
    17. <p>Modal Content</p>
    18. <p>Modal Content</p>
    19. <p>Modal Content</p>
    20. <p>Modal Content</p>
    21. <p>Modal Content</p>
    22. </div>
    23. <div *nzModalFooter>
    24. <span>Modal Footer: </span>
    25. <button nz-button nzType="default" (click)="handleCancel()">Custom Callback</button>
    26. <button nz-button nzType="primary" (click)="handleOk()" [nzLoading]="isConfirmLoading">Custom Submit</button>
    27. </div>
    28. </nz-modal>
    29. `,
    30. styles: []
    31. })
    32. export class NzDemoModalFooter2Component {
    33. isVisible = false;
    34. isConfirmLoading = false;
    35. constructor(private modalService: NzModalService) {}
    36. showModal1(): void {
    37. this.isVisible = true;
    38. }
    39. showModal2(): void {
    40. this.modalService.create({
    41. nzTitle: 'Modal Title',
    42. nzContent: NzModalCustomFooterComponent
    43. }
    44. handleOk(): void {
    45. this.isConfirmLoading = true;
    46. setTimeout(() => {
    47. this.isVisible = false;
    48. this.isConfirmLoading = false;
    49. }, 3000);
    50. }
    51. handleCancel(): void {
    52. this.isVisible = false;
    53. }
    54. }
    55. @Component({
    56. selector: 'nz-modal-custom-footer-component',
    57. template: `
    58. <div>
    59. <p>Modal Content</p>
    60. <p>Modal Content</p>
    61. <p>Modal Content</p>
    62. <p>Modal Content</p>
    63. <p>Modal Content</p>
    64. </div>
    65. <div *nzModalFooter>
    66. <button nz-button nzType="default" (click)="destroyModal()">Custom Callback</button>
    67. <button nz-button nzType="primary" (click)="destroyModal()">Custom Submit</button>
    68. </div>
    69. `
    70. })
    71. export class NzModalCustomFooterComponent {
    72. constructor(private modal: NzModalRef) {}
    73. destroyModal(): void {
    74. this.modal.destroy();
    75. }
    76. }

    Modal对话框 - 图9

    使用 NzModalService.confirm() 可以快捷地弹出确认框。NzOnCancel/NzOnOk 返回 promise 可以延迟关闭

    1. import { Component } from '@angular/core';
    2. import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal';
    3. @Component({
    4. selector: 'nz-demo-modal-confirm-promise',
    5. template: `
    6. <button nz-button nzType="info" (click)="showConfirm()">Confirm</button>
    7. `
    8. })
    9. export class NzDemoModalConfirmPromiseComponent {
    10. confirmModal: NzModalRef; // For testing by now
    11. constructor(private modal: NzModalService) {}
    12. showConfirm(): void {
    13. this.confirmModal = this.modal.confirm({
    14. nzTitle: 'Do you Want to delete these items?',
    15. nzContent: 'When clicked the OK button, this dialog will be closed after 1 second',
    16. nzOnOk: () =>
    17. new Promise((resolve, reject) => {
    18. setTimeout(Math.random() > 0.5 ? resolve : reject, 1000);
    19. }).catch(() => console.log('Oops errors!'))
    20. });
    21. }
    22. }

    设置 nzOkTextnzCancelText 以自定义按钮文字。

    Modal对话框 - 图11

    自定义位置

    您可以直接使用 nzStyle.top 或配合其他样式来设置对话框位置。

    1. import { Component } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-modal-position',
    4. template: `
    5. <button nz-button nzType="primary" (click)="showModalTop()">Display a modal dialog at 20px to Top</button>
    6. <nz-modal
    7. [nzStyle]="{ top: '20px' }"
    8. [(nzVisible)]="isVisibleTop"
    9. nzTitle="20px to Top"
    10. (nzOnCancel)="handleCancelTop()"
    11. (nzOnOk)="handleOkTop()"
    12. >
    13. <p>some contents...</p>
    14. <p>some contents...</p>
    15. <p>some contents...</p>
    16. </nz-modal>
    17. <br /><br />
    18. <button nz-button nzType="primary" (click)="showModalMiddle()">Vertically centered modal dialog</button>
    19. <nz-modal
    20. nzWrapClassName="vertical-center-modal"
    21. [(nzVisible)]="isVisibleMiddle"
    22. nzTitle="Vertically centered modal dialog"
    23. (nzOnCancel)="handleCancelMiddle()"
    24. (nzOnOk)="handleOkMiddle()"
    25. >
    26. <p>some contents...</p>
    27. <p>some contents...</p>
    28. <p>some contents...</p>
    29. </nz-modal>
    30. `,
    31. styles: [
    32. `
    33. ::ng-deep .vertical-center-modal {
    34. display: flex;
    35. align-items: center;
    36. justify-content: center;
    37. }
    38. ::ng-deep .vertical-center-modal .ant-modal {
    39. top: 0;
    40. }
    41. `
    42. ]
    43. })
    44. export class NzDemoModalPositionComponent {
    45. isVisibleTop = false;
    46. isVisibleMiddle = false;
    47. showModalTop(): void {
    48. this.isVisibleTop = true;
    49. }
    50. showModalMiddle(): void {
    51. this.isVisibleMiddle = true;
    52. }
    53. handleOkTop(): void {
    54. console.log('点击了确定');
    55. this.isVisibleTop = false;
    56. }
    57. handleCancelTop(): void {
    58. this.isVisibleTop = false;
    59. }
    60. handleOkMiddle(): void {
    61. console.log('click ok');
    62. this.isVisibleMiddle = false;
    63. }
    64. handleCancelMiddle(): void {
    65. this.isVisibleMiddle = false;
    66. }
    67. }

    对话框当前分为2种模式,普通模式确认框模式(即Confirm对话框,通过调用confirm/info/success/error/warning弹出),两种模式对API的支持程度稍有不同。

    注意

    采用服务方式创建普通模式对话框

    包括:

    • NzModalService.info
    • NzModalService.success
    • NzModalService.error
    • NzModalService.warning
    • NzModalService.confirm以上均为一个函数,参数为 object,与上方API一致。部分属性类型或初始值有所不同,已列在下方:

    以上函数调用后,会返回一个引用,可以通过该引用关闭弹窗。

    1. constructor(modal: NzModalService) {
    2. const ref: NzModalRef = modal.info();
    3. ref.close(); // 或 ref.destroy(); 将直接销毁对话框
    4. }

    NzModalService的其他方法/属性service

    NzModalRef

    通过服务方式 NzModalService.xxx() 创建的对话框,都会返回一个 NzModalRef 对象,用于操控该对话框(若使用nzContent为Component时,也可通过依赖注入 NzModalRef 方式获得此对象),该对象具有以下方法:

    全局配置(NZ_MODAL_CONFIG)如果要进行全局默认配置,你可以设置提供商 NZ_MODAL_CONFIG 的值来实现。(如:在你的模块的providers中加入 { provide: NZ_MODAL_CONFIG, useValue: { nzMask: false }}NZ_MODAL_CONFIG 可以从 ng-zorro-antd 中导入)

    全局配置,组件默认值,组件层级配置之间的权重如下:

    组件层级配置 > 全局配置 > 组件默认值

    当前支持的全局配置

    1. {
    2. provide: NZ_MODAL_CONFIG,
    3. useValue: {
    4. nzMask?: boolean; // 是否展示遮罩
    5. nzMaskClosable?: boolean; // 点击蒙层是否允许关闭
    6. }
    7. }

    注:全局配置并无默认值,因为nzMask和nzMaskClosable默认值存在于组件中

    ModalButtonOptions(用于自定义底部按钮)

    可将此类型数组传入 nzFooter,用于自定义底部按钮。

    按钮配置项如下(与button组件保持一致):

    1. nzFooter: [{
    2. label: string; // 按钮文本
    3. type?: string; // 类型
    4. shape?: string; // 形状
    5. ghost?: boolean; // 是否ghost
    6. size?: string; // 大小
    7. autoLoading?: boolean; // 默认为true,若为true时,当onClick返回promise时此按钮将自动置为loading状态
    8. // 提示:下方方法的this指向该配置对象自身。当nzContent为组件类时,下方方法传入的contentComponentInstance参数为该组件类的实例
    9. // 是否显示该按钮
    10. show?: boolean | ((this: ModalButtonOptions, contentComponentInstance?: object) => boolean);
    11. // 是否显示为loading
    12. loading?: boolean | ((this: ModalButtonOptions, contentComponentInstance?: object) => boolean);
    13. // 是否禁用
    14. disabled?: boolean | ((this: ModalButtonOptions, contentComponentInstance?: object) => boolean);
    15. // 按钮点击回调
    16. }]

    以上配置项也可在运行态实时改变,来触发按钮行为改变。

    另一种自定义页脚按钮的方式。