Skip to content

Commit

Permalink
fix(module:modal): close modal itself before destructing by the angul…
Browse files Browse the repository at this point in the history
…ar's lifecycle

close #1663
  • Loading branch information
wilsoncook committed Jul 1, 2018
1 parent 92675e4 commit a963e58
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 7 deletions.
2 changes: 2 additions & 0 deletions components/modal/doc/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ The dialog is currently divided into 2 modes, `normal mode` and `confirm box mod

> The default state of `<nz-modal>` will not be automatically cleared. If you wish to open new content each time, use the `NzModalService` service to create modals (when created as a service, the `nzAfterClose` event will be listened by default aim to destroy the modal).
> Modals created through the `NzModalService` service need you to manage their own life cycle. For example, when you switch the page route, the modal box created by service will not be destroyed automatically. You need to use the modal box's reference to manually destroy it (`NzModalRef.close()` or `NzModalRef.destroy()`).
#### Using service to create Normal Mode modal

> You can call `NzModalService.create(options)` to dynamically create **normal mode** modals, where `options` is an object that supports the support given in the API above **normal mode** parameters
Expand Down
2 changes: 2 additions & 0 deletions components/modal/doc/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ title: Modal

> `<nz-modal>` 默认关闭后状态不会自动清空, 如果希望每次打开都是新内容,请采用 `NzModalService` 服务方式创建对话框(当以服务方式创建时,默认会监听 `nzAfterClose` 并销毁对话框)。
> 通过 `NzModalService` 服务方式创建的对话框需要自行管理其生命周期。比如你在页面路由切换时,服务方式创建的对话框并不会被销毁,你需要使用对话框引用来手动销毁(`NzModalRef.close()``NzModalRef.destroy()`)。
#### 采用服务方式创建普通模式对话框

> 您可调用 `NzModalService.create(options)` 来动态创建**普通模式**对话框,这里的 `options` 是一个对象,支持上方API中给出的支持 **普通模式** 的参数
Expand Down
13 changes: 11 additions & 2 deletions components/modal/nz-modal-control.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,17 @@ export class NzModalControlService {
}
}

// TODO: allow deregister modals
// deregisterModal(modalRef: NzModalRef): void {}
// deregister modals
deregisterModal(modalRef: NzModalRef): void {
const registeredMeta = this.registeredMetaMap.get(modalRef);
if (registeredMeta) {
// Remove this modal if it is still in the opened modal list (NOTE: it may trigger "afterAllClose")
this.removeOpenModal(registeredMeta.modalRef);
registeredMeta.afterOpenSubscription.unsubscribe();
registeredMeta.afterCloseSubscription.unsubscribe();
this.registeredMetaMap.delete(modalRef);
}
}

hasRegistered(modalRef: NzModalRef): boolean {
return this.registeredMetaMap.has(modalRef);
Expand Down
16 changes: 11 additions & 5 deletions components/modal/nz-modal.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,17 @@ export class NzModalComponent<T = any, R = any> extends NzModalRef<T, R> impleme
}

ngOnDestroy(): void {
if (this.container instanceof OverlayRef) {
this.container.dispose();
}
this.unsubscribe$.next();
this.unsubscribe$.complete();
// Close self before destructing
this.changeVisibleFromInside(false).then(() => {
this.modalControl.deregisterModal(this);

if (this.container instanceof OverlayRef) {
this.container.dispose();
}

this.unsubscribe$.next();
this.unsubscribe$.complete();
});
}

open(): void {
Expand Down
31 changes: 31 additions & 0 deletions components/modal/nz-modal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ describe('NzModal', () => {
imports: [ NzModalModule ],
providers : [ NzMeasureScrollbarService ],
declarations: [
NzDemoModalBasicComponent,
ModalByServiceComponent
]
});
Expand All @@ -348,6 +349,25 @@ describe('NzModal', () => {
overlayContainer.ngOnDestroy();
});

describe('basic usage', () => {
let fixture: ComponentFixture<NzDemoModalBasicComponent>;
beforeEach(() => {
fixture = TestBed.createComponent(NzDemoModalBasicComponent);
});

it('should destroy normally when the component context is over', fakeAsync(() => {
fixture.detectChanges();
tick(1000);
fixture.detectChanges();
expect(overlayContainerElement.textContent).toContain('BASIC_MODAL_TITLE');
fixture.componentInstance.modalAvailable = false;
fixture.detectChanges();
tick(1000);
fixture.detectChanges();
expect(overlayContainerElement.textContent).not.toContain('BASIC_MODAL_TITLE');
}));
});

describe('created by service', () => {
let fixture: ComponentFixture<ModalByServiceComponent>;

Expand Down Expand Up @@ -480,6 +500,17 @@ describe('NzModal', () => {
// | Testing Components
// -------------------------------------------

@Component({
template: `
<nz-modal *ngIf="modalAvailable" nzVisible nzTitle="BASIC_MODAL_TITLE">
<p>content</p>
</nz-modal>
`
})
class NzDemoModalBasicComponent {
modalAvailable = true;
}

@Component({
selector: 'nz-demo-modal-async',
template: `
Expand Down

0 comments on commit a963e58

Please sign in to comment.