Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/framework/theme/components/dialog/dialog-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import { InjectionToken, ViewContainerRef } from '@angular/core';


export const NB_DIALOG_CONFIG = new InjectionToken<NbDialogConfig>('Default dialog options');

/**
Expand Down Expand Up @@ -56,6 +55,9 @@ export class NbDialogConfig<D = any> {
*/
viewContainerRef: ViewContainerRef;

/** Closes dialog automatically on navigation events such as browser back button pressed */
closeOnNavigation: boolean = true;

context: D;

constructor(config: Partial<NbDialogConfig>) {
Expand Down
66 changes: 40 additions & 26 deletions src/framework/theme/components/dialog/dialog.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import { ComponentFactoryResolver, Inject, Injectable, Injector, TemplateRef, Type } from '@angular/core';
import { Router, NavigationStart } from '@angular/router';
import { fromEvent as observableFromEvent } from 'rxjs';
import { filter, takeUntil } from 'rxjs/operators';

Expand All @@ -22,7 +23,6 @@ import { NB_DIALOG_CONFIG, NbDialogConfig } from './dialog-config';
import { NbDialogRef } from './dialog-ref';
import { NbDialogContainerComponent } from './dialog-container';


/**
* The `NbDialogService` helps to open dialogs.
*
Expand Down Expand Up @@ -138,19 +138,23 @@ import { NbDialogContainerComponent } from './dialog-container';
* */
@Injectable()
export class NbDialogService {
constructor(@Inject(NB_DOCUMENT) protected document,
@Inject(NB_DIALOG_CONFIG) protected globalConfig,
protected positionBuilder: NbPositionBuilderService,
protected overlay: NbOverlayService,
protected injector: Injector,
protected cfr: ComponentFactoryResolver) {
}
constructor(
@Inject(NB_DOCUMENT) protected document,
@Inject(NB_DIALOG_CONFIG) protected globalConfig,
protected positionBuilder: NbPositionBuilderService,
protected overlay: NbOverlayService,
protected injector: Injector,
protected cfr: ComponentFactoryResolver,
protected router: Router,
) {}

/**
* Opens new instance of the dialog, may receive optional config.
* */
open<T>(content: Type<T> | TemplateRef<T>,
userConfig: Partial<NbDialogConfig<Partial<T> | string>> = {}): NbDialogRef<T> {
open<T>(
content: Type<T> | TemplateRef<T>,
userConfig: Partial<NbDialogConfig<Partial<T> | string>> = {},
): NbDialogRef<T> {
const config = new NbDialogConfig({ ...this.globalConfig, ...userConfig });
const overlayRef = this.createOverlay(config);
const dialogRef = new NbDialogRef<T>(overlayRef);
Expand All @@ -159,6 +163,13 @@ export class NbDialogService {

this.registerCloseListeners(config, overlayRef, dialogRef);

if (userConfig?.closeOnNavigation !== false) {
const subscription = this.router.events
.pipe(filter((event) => event instanceof NavigationStart))
.subscribe(() => dialogRef.close());

dialogRef.onClose.subscribe(() => subscription.unsubscribe());
}
return dialogRef;
}

Expand All @@ -176,10 +187,7 @@ export class NbDialogService {
}

protected createPositionStrategy(): NbGlobalPositionStrategy {
return this.positionBuilder
.global()
.centerVertically()
.centerHorizontally();
return this.positionBuilder.global().centerVertically().centerHorizontally();
}

protected createScrollStrategy(hasScroll: boolean): NbScrollStrategy {
Expand All @@ -197,10 +205,12 @@ export class NbDialogService {
return containerRef.instance;
}

protected createContent<T>(config: NbDialogConfig,
content: Type<T> | TemplateRef<T>,
container: NbDialogContainerComponent,
dialogRef: NbDialogRef<T>) {
protected createContent<T>(
config: NbDialogConfig,
content: Type<T> | TemplateRef<T>,
container: NbDialogContainerComponent,
dialogRef: NbDialogRef<T>,
) {
if (content instanceof TemplateRef) {
const portal = this.createTemplatePortal(config, content, dialogRef);
container.attachTemplatePortal(portal);
Expand All @@ -209,31 +219,35 @@ export class NbDialogService {
dialogRef.componentRef = container.attachComponentPortal(portal);

if (config.context) {
Object.assign(dialogRef.componentRef.instance, { ...config.context })
Object.assign(dialogRef.componentRef.instance, { ...config.context });
}
}
}

protected createTemplatePortal<T>(config: NbDialogConfig,
content: TemplateRef<T>,
dialogRef: NbDialogRef<T>): NbTemplatePortal {
protected createTemplatePortal<T>(
config: NbDialogConfig,
content: TemplateRef<T>,
dialogRef: NbDialogRef<T>,
): NbTemplatePortal {
return new NbTemplatePortal(content, null, <any>{ $implicit: config.context, dialogRef });
}

/**
* We're creating portal with custom injector provided through config or using global injector.
* This approach provides us capability inject `NbDialogRef` in dialog component.
* */
protected createComponentPortal<T>(config: NbDialogConfig,
content: Type<T>,
dialogRef: NbDialogRef<T>): NbComponentPortal {
protected createComponentPortal<T>(
config: NbDialogConfig,
content: Type<T>,
dialogRef: NbDialogRef<T>,
): NbComponentPortal {
const injector = this.createInjector(config);
const portalInjector = new NbPortalInjector(injector, new WeakMap([[NbDialogRef, dialogRef]]));
return new NbComponentPortal(content, config.viewContainerRef, portalInjector);
}

protected createInjector(config: NbDialogConfig): Injector {
return config.viewContainerRef && config.viewContainerRef.injector || this.injector;
return (config.viewContainerRef && config.viewContainerRef.injector) || this.injector;
}

protected registerCloseListeners<T>(config: NbDialogConfig, overlayRef: NbOverlayRef, dialogRef: NbDialogRef<T>) {
Expand Down