Skip to content

Commit

Permalink
fix(toastr): dispose no longer used overlay container (#1873)
Browse files Browse the repository at this point in the history
  • Loading branch information
yggg authored Oct 10, 2019
1 parent 3ec69e7 commit 4114ad1
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@

import { Component, Input, OnDestroy, OnInit, QueryList, ViewChildren } from '@angular/core';
import { animate, style, transition, trigger } from '@angular/animations';
import { takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';

import { NbToastComponent } from './toast.component';
import { NbToast } from './model';
import { NbLayoutDirectionService } from '../../services/direction.service';
import { NbGlobalPosition, NbPositionHelper } from '../cdk/overlay/position-helper';
import { takeWhile } from 'rxjs/operators';


const voidState = style({
transform: 'translateX({{ direction }}110%)',
Expand All @@ -37,6 +37,9 @@ const defaultOptions = { params: { direction: '' } };
],
})
export class NbToastrContainerComponent implements OnInit, OnDestroy {

protected destroy$ = new Subject<void>();

@Input()
content: NbToast[] = [];

Expand All @@ -51,20 +54,19 @@ export class NbToastrContainerComponent implements OnInit, OnDestroy {

fadeIn;

protected alive: boolean = true;

constructor(protected layoutDirection: NbLayoutDirectionService,
protected positionHelper: NbPositionHelper) {
}

ngOnInit() {
this.layoutDirection.onDirectionChange()
.pipe(takeWhile(() => this.alive))
.pipe(takeUntil(this.destroy$))
.subscribe(() => this.onDirectionChange());
}

ngOnDestroy() {
this.alive = false;
this.destroy$.next();
this.destroy$.complete();
}

protected onDirectionChange() {
Expand Down
11 changes: 11 additions & 0 deletions src/framework/theme/components/toastr/toastr.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ describe('toastr-container-registry', () => {
},
}
},
dispose() {},
};

overlayStub = {
Expand Down Expand Up @@ -223,6 +224,16 @@ describe('toastr-container-registry', () => {

expect(topEnd).toBe(topRight);
});

it('should dispose overlay before replacing with new one', () => {
toastrContainerRegistry.get(NbGlobalLogicalPosition.TOP_END);

const overlayDisposeSpy = spyOn(containerStub, 'dispose');
documentStub._contains = false;
toastrContainerRegistry.get(NbGlobalLogicalPosition.TOP_END);

expect(overlayDisposeSpy).toHaveBeenCalledTimes(1);
});
});

describe('toastr-container', () => {
Expand Down
28 changes: 19 additions & 9 deletions src/framework/theme/components/toastr/toastr.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { ComponentFactoryResolver, ComponentRef, Inject, Injectable } from '@angular/core';

import { NbComponentPortal } from '../cdk/overlay/mapping';
import { NbComponentPortal, NbOverlayRef } from '../cdk/overlay/mapping';
import { NbOverlayService, patch } from '../cdk/overlay/overlay-service';
import { NbPositionBuilderService } from '../cdk/overlay/overlay-position';
import { NbGlobalLogicalPosition, NbGlobalPosition, NbPositionHelper } from '../cdk/overlay/position-helper';
Expand Down Expand Up @@ -133,10 +133,14 @@ export class NbToastContainer {
}
}

interface NbToastrOverlayWithContainer {
overlayRef: NbOverlayRef;
toastrContainer: NbToastContainer;
}

@Injectable()
export class NbToastrContainerRegistry {
protected overlays: Map<NbGlobalPosition, NbToastContainer> = new Map();
protected overlays: Map<NbGlobalPosition, NbToastrOverlayWithContainer> = new Map();

constructor(protected overlay: NbOverlayService,
protected positionBuilder: NbPositionBuilderService,
Expand All @@ -148,24 +152,30 @@ export class NbToastrContainerRegistry {
get(position: NbGlobalPosition): NbToastContainer {
const logicalPosition: NbGlobalLogicalPosition = this.positionHelper.toLogicalPosition(position);

const container = this.overlays.get(logicalPosition);
if (!container || !this.existsInDom(container)) {
const overlayWithContainer = this.overlays.get(logicalPosition);
if (!overlayWithContainer || !this.existsInDom(overlayWithContainer.toastrContainer)) {
if (overlayWithContainer) {
overlayWithContainer.overlayRef.dispose();
}
this.instantiateContainer(logicalPosition);
}

return this.overlays.get(logicalPosition);
return this.overlays.get(logicalPosition).toastrContainer;
}

protected instantiateContainer(position: NbGlobalLogicalPosition) {
const container = this.createContainer(position);
this.overlays.set(position, container);
const toastrOverlayWithContainer = this.createContainer(position);
this.overlays.set(position, toastrOverlayWithContainer);
}

protected createContainer(position: NbGlobalLogicalPosition): NbToastContainer {
protected createContainer(position: NbGlobalLogicalPosition): NbToastrOverlayWithContainer {
const positionStrategy = this.positionBuilder.global().position(position);
const ref = this.overlay.create({ positionStrategy });
const containerRef = ref.attach(new NbComponentPortal(NbToastrContainerComponent, null, null, this.cfr));
return new NbToastContainer(position, containerRef, this.positionHelper);
return {
overlayRef: ref,
toastrContainer: new NbToastContainer(position, containerRef, this.positionHelper),
};
}

protected existsInDom(toastContainer: NbToastContainer): boolean {
Expand Down

0 comments on commit 4114ad1

Please sign in to comment.