Skip to content

Commit

Permalink
feat(module:modal): add afterOpen/afterClose/afterAllClose/closeAll/o…
Browse files Browse the repository at this point in the history
…penModals, adjust the boolean props and changeBodyOverflow and complete testing. (#1165)

* feat(module:modal): add afterClose and more to improve communication capabilities

close #1155

* feat(module:modal): add afterOpen/afterAllClose/closeAll/openModals, adjust the boolean props and changeBodyOverflow, complete testing.

close #1162

* docs(changelog): add 0.7.0-beta.2 changelog for modal
  • Loading branch information
wilsoncook authored and vthinkxie committed Mar 19, 2018
1 parent ab37862 commit 10227b8
Show file tree
Hide file tree
Showing 19 changed files with 607 additions and 211 deletions.
2 changes: 1 addition & 1 deletion components/core/style/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
.cdk-overlay-pane {
position: absolute;
pointer-events: auto;
z-index: 1000;
// z-index: 1000; // Give an opportunity to the content own to manage their z-index such as Modal
}

.box-shadow-left() {
Expand Down
6 changes: 3 additions & 3 deletions components/modal/demo/async.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Component } from '@angular/core';
<button nz-button nzType="primary" (click)="showModal()">
<span>Show Modal</span>
</button>
<nz-modal [(nzVisible)]="isVisible" nzTitle="Modal Title" (nzOnCancel)="handleCancel($event)" (nzOnOk)="handleOk($event)" [nzOkLoading]="isOkLoading">
<nz-modal [(nzVisible)]="isVisible" nzTitle="Modal Title" (nzOnCancel)="handleCancel()" (nzOnOk)="handleOk()" [nzOkLoading]="isOkLoading">
<p>Modal Content</p>
</nz-modal>
`,
Expand All @@ -20,15 +20,15 @@ export class NzDemoModalAsyncComponent {
this.isVisible = true;
}

handleOk($event: MouseEvent): void {
handleOk(): void {
this.isOkLoading = true;
window.setTimeout(() => {
this.isVisible = false;
this.isOkLoading = false;
}, 3000);
}

handleCancel($event: MouseEvent): void {
handleCancel(): void {
this.isVisible = false;
}
}
21 changes: 15 additions & 6 deletions components/modal/demo/basic.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,42 @@
import { Component } from '@angular/core';
import { Component, ViewChild, OnInit } from '@angular/core';
import { NzModalComponent } from 'ng-zorro-antd';

@Component({
selector: 'nz-demo-modal-basic',
template: `
<button nz-button [nzType]="'primary'" (click)="showModal()"><span>Show Modal</span></button>
<nz-modal [(nzVisible)]="isVisible" nzTitle="The first Modal" (nzOnCancel)="handleCancel($event)" (nzOnOk)="handleOk($event)">
<nz-modal #modal *ngIf="modalValid" [(nzVisible)]="isVisible" nzTitle="The first Modal" (nzOnCancel)="handleCancel()" (nzOnOk)="handleOk()">
<p>Content one</p>
<p>Content two</p>
<p>Content three</p>
</nz-modal>
`,
styles: []
})
export class NzDemoModalBasicComponent {
export class NzDemoModalBasicComponent implements OnInit {
isVisible = false;
modalValid = true;

@ViewChild('modal') private modal: NzModalComponent;

constructor() {}

ngOnInit(): void {
(window as any).modal = this.modal; // tslint:disable-line
}

showModal(): void {
this.isVisible = true;
window.setTimeout(() => this.modalValid = false, 2000);
}

handleOk($event: MouseEvent): void {
handleOk(): void {
console.log('Button ok clicked!');
this.isVisible = false;
}

handleCancel($event: MouseEvent): void {
console.log('Button cancel clicked!', $event);
handleCancel(): void {
console.log('Button cancel clicked!');
this.isVisible = false;
}
}
4 changes: 2 additions & 2 deletions components/modal/demo/confirm-promise.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component } from '@angular/core';
import { ModalPublicAgent, NzModalService } from 'ng-zorro-antd';
import { NzModalRef, NzModalService } from 'ng-zorro-antd';

@Component({
selector: 'nz-demo-modal-confirm-promise',
Expand All @@ -9,7 +9,7 @@ import { ModalPublicAgent, NzModalService } from 'ng-zorro-antd';
styles : []
})
export class NzDemoModalConfirmPromiseComponent {
confirmModal: ModalPublicAgent; // For testing by now
confirmModal: NzModalRef; // For testing by now

constructor(private modal: NzModalService) { }

Expand Down
10 changes: 5 additions & 5 deletions components/modal/demo/footer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Component } from '@angular/core';
<button nz-button nzType="primary" (click)="showModal()">
<span>Show Modal</span>
</button>
<nz-modal [(nzVisible)]="isVisible" [nzTitle]="modalTitle" [nzContent]="modalContent" [nzFooter]="modalFooter" (nzOnCancel)="handleCancel($event)">
<nz-modal [(nzVisible)]="isVisible" [nzTitle]="modalTitle" [nzContent]="modalContent" [nzFooter]="modalFooter" (nzOnCancel)="handleCancel()">
<ng-template #modalTitle>
Custom Modal Title
</ng-template>
Expand All @@ -22,8 +22,8 @@ import { Component } from '@angular/core';
<ng-template #modalFooter>
<span>Modal Footer: </span>
<button nz-button nzType="default" (click)="handleCancel($event)">Custom Callback</button>
<button nz-button nzType="primary" (click)="handleOk($event)" [nzLoading]="isConfirmLoading">Custom Submit</button>
<button nz-button nzType="default" (click)="handleCancel()">Custom Callback</button>
<button nz-button nzType="primary" (click)="handleOk()" [nzLoading]="isConfirmLoading">Custom Submit</button>
</ng-template>
</nz-modal>
`,
Expand All @@ -39,15 +39,15 @@ export class NzDemoModalFooterComponent {
this.isVisible = true;
}

handleOk($event: MouseEvent): void {
handleOk(): void {
this.isConfirmLoading = true;
setTimeout(() => {
this.isVisible = false;
this.isConfirmLoading = false;
}, 3000);
}

handleCancel($event: MouseEvent): void {
handleCancel(): void {
this.isVisible = false;
}
}
42 changes: 35 additions & 7 deletions components/modal/demo/service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* entryComponents: NzModalCustomComponent */

import { Component, Input, TemplateRef } from '@angular/core';
import { ModalPublicAgent, NzModalService } from 'ng-zorro-antd';
import { Component, Input, TemplateRef, ViewChild } from '@angular/core';
import { NzModalRef, NzModalService } from 'ng-zorro-antd';

@Component({
selector: 'nz-demo-modal-service',
Expand Down Expand Up @@ -34,11 +34,17 @@ import { ModalPublicAgent, NzModalService } from 'ng-zorro-antd';
</button>
<button nz-button nzType="primary" (click)="createCustomButtonModal()">Custom Button</button>
<br /><br />
<button nz-button nzType="primary" (click)="openAndCloseAll()">Open more modals then close all after 2s</button>
<nz-modal [(nzVisible)]="htmlModalVisible" nzMask="false" nzZIndex="1001" nzTitle="Non-service html modal">This is a non-service html modal</nz-modal>
`
})
export class NzDemoModalServiceComponent {
tplModal: ModalPublicAgent;
tplModal: NzModalRef;
tplModalButtonLoading = false;
htmlModalVisible = false;

constructor(private modalService: NzModalService) { }

Expand Down Expand Up @@ -80,15 +86,20 @@ export class NzDemoModalServiceComponent {
},
nzFooter: [{
label: 'change component tilte from outside',
onClick: (componentInstance: NzModalCustomComponent) => {
onClick: (componentInstance) => {
componentInstance.title = 'title in inner component is changed';
}
}]
});

modal.afterOpen.subscribe(() => console.log('[afterOpen] emitted!'));

// Return a result when closed
modal.afterClose.subscribe((result) => console.log('[afterClose] The result is:', result));

// delay until modal instance created
window.setTimeout(() => {
const instance = modal.getContentComponentRef().instance as NzModalCustomComponent;
const instance = modal.getContentComponent();
instance.subtitle = 'sub title is changed';
}, 2000);
}
Expand Down Expand Up @@ -130,6 +141,23 @@ export class NzDemoModalServiceComponent {
]
});
}

openAndCloseAll(): void {
let pos = 0;

[ 'create', 'info', 'success', 'error' ].forEach((method) => this.modalService[method]({
nzMask: false,
nzTitle: `Test ${method} title`,
nzContent: `Test content: <b>${method}</b>`,
nzStyle: { position: 'absolute', top: `${pos * 70}px`, left: `${(pos++) * 300}px` }
}));

this.htmlModalVisible = true;

this.modalService.afterAllClose.subscribe(() => console.log('afterAllClose emitted!'));

window.setTimeout(() => this.modalService.closeAll(), 2000);
}
}

@Component({
Expand All @@ -149,9 +177,9 @@ export class NzModalCustomComponent {
@Input() title: string;
@Input() subtitle: string;

constructor(private modal: ModalPublicAgent) { }
constructor(private modal: NzModalRef) { }

destroyModal(): void {
this.modal.destroy();
this.modal.destroy({ data: 'this the result data' });
}
}
37 changes: 25 additions & 12 deletions components/modal/doc/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ getting feedback or information purposes.
Additionally, if you need show a simple confirmation dialog, you can use `NzModalService.confirm()`,
and so on.

It is recommended to use the `Component` way to pop up the Modal, so that the component logic of the popup layer can be completely isolated from the outer component, and can be reused at any time. In the popup layer component, you can obtain Modal's component instance by injecting `ModalPublicAgent` to control the behavior of the modal box.
It is recommended to use the `Component` way to pop up the Modal, so that the component logic of the popup layer can be completely isolated from the outer component, and can be reused at any time. In the popup layer component, you can obtain Modal's component instance by injecting `NzModalRef` to control the behavior of the modal box.


## API
Expand All @@ -23,14 +23,15 @@ The dialog is currently divided into 2 modes, `normal mode` and `confirm box mod

| Property | Description | Type | Default |
|----|----|----|----|
| nzAfterClose | Specify a EventEmitter that will be emitted when modal is closed completely. | EventEmitter | - |
| nzAfterOpen | Specify a EventEmitter that will be emitted when modal opened | EventEmitter | - |
| nzAfterClose | Specify a EventEmitter that will be emitted when modal is closed completely (Can listen for parameters passed in the close/destroy method) | EventEmitter | - |
| nzBodyStyle | Body style for modal body element. Such as height, padding etc. | object | - |
| nzCancelText | Text of the Cancel button. <i>Set to null to show no cancel button (this value is invalid if the nzFooter parameter is used in normal mode)</i> | string | Cancel |
| nzClosable | Whether a close (x) button is visible on top right of the modal dialog or not. <i>Invalid value in confirm box mode (default will be hidden)</i> | boolean | true |
| nzOkLoading | Whether to apply loading visual effect for OK button or not | boolean | false |
| nzCancelLoading | Whether to apply loading visual effect for Cancel button or not | boolean | false |
| nzFooter | Footer content, set as footer=null when you don't need default buttons. <i>1. Only valid in normal mode.<br>2. You can customize the buttons to the maximum extent by passing a `ModalButtonOptions` configuration (see the case or the instructions below).</i> | string<br>TemplateRef<br>ModalButtonOptions | OK and Cancel buttons |
| nzGetContainer | The mount node for Modal | HTMLElement / () => HTMLElement| Handled by overlay container |
| nzGetContainer | The mount node for Modal | HTMLElement / () => HTMLElement| A default container |
| nzMask | Whether show mask or not. | boolean | true |
| nzMaskClosable | Whether to close the modal dialog when the mask (area outside the modal) is clicked | boolean | true |
| nzMaskStyle | Style for modal's mask element. | object | - |
Expand All @@ -42,8 +43,8 @@ The dialog is currently divided into 2 modes, `normal mode` and `confirm box mod
| nzWidth | Width of the modal dialog. <i>When using numbers, the default unit is `px`</i> | string<br>number | 520 |
| nzWrapClassName | The class name of the container of the modal dialog | string | - |
| nzZIndex | The z-index of the Modal | number | 1000 |
| nzOnCancel | Specify a function that will be called when a user clicks mask, close button on top right or Cancel button. <i>Note: When created with `NzModalService.create`, this parameter should be passed into the type of function (callback function). This function returns a promise, which is automatically closed when the execution is complete or the promise ends (return `false` to prevent closing)</i> | EventEmitter | - |
| nzOnOk | Specify a EventEmitter that will be emitted when a user clicks the OK button | EventEmitter ||
| nzOnCancel | Specify a function that will be called when a user clicks mask, close button on top right or Cancel button (If nzContent is Component, the Component instance will be put in as an argument). <i>Note: When created with `NzModalService.create`, this parameter should be passed into the type of function (callback function). This function returns a promise, which is automatically closed when the execution is complete or the promise ends (return `false` to prevent closing)</i> | EventEmitter | - |
| nzOnOk | Specify a EventEmitter that will be emitted when a user clicks the OK button (If nzContent is Component, the Component instance will be put in as an argument). <i>Note: When created with `NzModalService.create`, this parameter should be passed into the type of function (callback function). This function returns a promise, which is automatically closed when the execution is complete or the promise ends (return `false` to prevent closing)</i> | EventEmitter ||
| nzContent | Content | string / TemplateRef / Component / ng-content | - |
| nzComponentParams | When nzContent is a Component, the attributes in this parameter will be passed to the nzContent instance | object | - |
| nzIconType | Icon type of the Icon component. <i>Only valid in confirm box mode</i> | string | question-circle |
Expand Down Expand Up @@ -71,32 +72,44 @@ Consistent with the above API, some property types or initial values are differe

| Property | Description | Type | Default |
|------------|----------------|------------------|---------------|
| nzOnOk | Specify a EventEmitter that will be emitted when a user clicks the OK button. <i>This function returns a promise, which is automatically closed when the execution is complete or the promise ends (return `false` to prevent closing)</i> | function | - |
| nzOnCancel | Specify a function that will be called when a user clicks mask, close button on top right or Cancel button. <i>This function returns a promise, which is automatically closed when the execution is complete or the promise ends (return `false` to prevent closing)</i> | function | - |
| nzOnOk | Specify a EventEmitter that will be emitted when a user clicks the OK button (If nzContent is Component, the Component instance will be put in as an argument.). <i>This function returns a promise, which is automatically closed when the execution is complete or the promise ends (return `false` to prevent closing)</i> | function | - |
| nzOnCancel | Specify a function that will be called when a user clicks mask, close button on top right or Cancel button (If nzContent is Component, the Component instance will be put in as an argument.). <i>This function returns a promise, which is automatically closed when the execution is complete or the promise ends (return `false` to prevent closing)</i> | function | - |
| nzWidth | Width of the modal dialog | string / number | 416 |
| nzMaskClosable | Whether to close the modal dialog when the mask (area outside the modal) is clicked | boolean | false |

All the `NzModalService.method`s will return a reference, and then we can close the popup by the reference.

```ts
constructor(modal: NzModalService) {
const ref: ModalPublicAgent = modal.info();
ref.destroy(); // Note: This dialog will be destroyed directly
const ref: NzModalRef = modal.info();
ref.close(); // Or ref.destroy(); This dialog will be destroyed directly
}
```

### Related type definition

#### ModalPublicAgent (used for control dialogs)
#### Other Methods/Attributes for NzModalService

The dialog created by the service method `NzModalService.xxx()` will return a `ModalPublicAgent` object that is used to manipulate the dialog (this object can also be obtained by dependency injection `ModalPublicAgent` if `nzContent` is used as Component) , This object has the following methods:
| Methods/Attributes | Description | Type |
|----|----|
| openModals | All currently open Modal list | NzModalRef[] |
| afterAllClose | Callback called after all Modals closed completely | Observable&lt;void&gt; |
| closeAll() | Close all modals | function |

#### NzModalRef

> NzModalRef object is used to control dialogs and communicate with inside content
The dialog created by the service method `NzModalService.xxx()` will return a `NzModalRef` object that is used to manipulate the dialog (this object can also be obtained by dependency injection `NzModalRef` if `nzContent` is used as Component) , This object has the following methods:

| Method | Description |
|----|----|
| afterOpen | Same as nzAfterOpen but of type Observable&lt;void&gt; |
| afterClose | Same as nzAfterClose, but of type Observable&lt;result:any&gt; |
| open() | Open (display) dialog box. <i>Calling this function will fail if the dialog is already destroyed</i> |
| close() | Close (hide) the dialog. <i>Note: When used for a dialog created as a service, this method will destroy the dialog directly (as with the destroy method)</i> |
| destroy() | Destroy the dialog. <i>Note: Used only for dialogs created by the service (non-service created dialogs, this method only hides the dialog)</i> |
| getContentComponentRef() | Gets a Component reference (of type `ComponentRef`) in the contents of the dialog for `nzContent`. <i> Note: When the dialog is not initialized (`ngOnInit` is not executed), this function will return `undefined`</i> |
| getContentComponent() | Gets the Component instance in the contents of the dialog for `nzContent`. <i> Note: When the dialog is not initialized (`ngOnInit` is not executed), this function will return `undefined`</i> |

#### ModalButtonOptions (used to customize the bottom button)

Expand Down
Loading

0 comments on commit 10227b8

Please sign in to comment.