mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(dialog): allow disableClose option to be updated (#4964)
* Exposes the disableClose option via the `MdDialogRef` and allows for it to be updated. * Makes the `containerInstance` private to `MdDialogRef` since it doesn't make sense for it to be public anymore. * Completes the `backdropClick` observable once the associated `overlayRef` is destroyed. This avoids having to unsubscribe manually or having to use `Observable.first`. Fixes #3938.
This commit is contained in:
committed by
Andrew Seguin
parent
657f0e829e
commit
66629cf1ed
@@ -100,6 +100,7 @@ export class OverlayRef implements PortalHost {
|
||||
this.detachBackdrop();
|
||||
this._portalHost.dispose();
|
||||
this._attachments.complete();
|
||||
this._backdropClick.complete();
|
||||
this._detachments.next();
|
||||
this._detachments.complete();
|
||||
}
|
||||
|
||||
@@ -327,6 +327,21 @@ describe('Overlay', () => {
|
||||
expect(backdropClickHandler).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should complete the backdrop click stream once the overlay is destroyed', () => {
|
||||
let overlayRef = overlay.create(config);
|
||||
|
||||
overlayRef.attach(componentPortal);
|
||||
viewContainerFixture.detectChanges();
|
||||
|
||||
let backdrop = overlayContainerElement.querySelector('.cdk-overlay-backdrop') as HTMLElement;
|
||||
let completeHandler = jasmine.createSpy('backdrop complete handler');
|
||||
|
||||
overlayRef.backdropClick().subscribe(null, null, completeHandler);
|
||||
overlayRef.dispose();
|
||||
|
||||
expect(completeHandler).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should apply the default overlay backdrop class', () => {
|
||||
let overlayRef = overlay.create(config);
|
||||
overlayRef.attach(componentPortal);
|
||||
|
||||
@@ -57,7 +57,7 @@ export function throwMdDialogContentAlreadyAttachedError() {
|
||||
],
|
||||
host: {
|
||||
'[class.mat-dialog-container]': 'true',
|
||||
'[attr.role]': 'dialogConfig?.role',
|
||||
'[attr.role]': 'config?.role',
|
||||
'[@slideDialog]': '_state',
|
||||
'(@slideDialog.done)': '_onAnimationDone($event)',
|
||||
},
|
||||
@@ -76,7 +76,7 @@ export class MdDialogContainer extends BasePortalHost {
|
||||
private _document: Document;
|
||||
|
||||
/** The dialog configuration. */
|
||||
dialogConfig: MdDialogConfig;
|
||||
config: MdDialogConfig;
|
||||
|
||||
/** State of the dialog animation. */
|
||||
_state: 'void' | 'enter' | 'exit' = 'enter';
|
||||
|
||||
@@ -18,13 +18,16 @@ export class MdDialogRef<T> {
|
||||
/** The instance of component opened into the dialog. */
|
||||
componentInstance: T;
|
||||
|
||||
/** Whether the user is allowed to close the dialog. */
|
||||
disableClose: boolean = this._containerInstance.config.disableClose;
|
||||
|
||||
/** Subject for notifying the user that the dialog has finished closing. */
|
||||
private _afterClosed: Subject<any> = new Subject();
|
||||
|
||||
/** Result to be passed to afterClosed. */
|
||||
private _result: any;
|
||||
|
||||
constructor(private _overlayRef: OverlayRef, public _containerInstance: MdDialogContainer) {
|
||||
constructor(private _overlayRef: OverlayRef, private _containerInstance: MdDialogContainer) {
|
||||
_containerInstance._onAnimationStateChange
|
||||
.filter((event: AnimationEvent) => event.toState === 'exit')
|
||||
.subscribe(() => this._overlayRef.dispose(), null, () => {
|
||||
|
||||
@@ -451,6 +451,28 @@ describe('MdDialog', () => {
|
||||
|
||||
expect(overlayContainerElement.querySelector('md-dialog-container')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow for the disableClose option to be updated while open', async(() => {
|
||||
let dialogRef = dialog.open(PizzaMsg, {
|
||||
disableClose: true,
|
||||
viewContainerRef: testViewContainerRef
|
||||
});
|
||||
|
||||
viewContainerFixture.detectChanges();
|
||||
|
||||
let backdrop = overlayContainerElement.querySelector('.cdk-overlay-backdrop') as HTMLElement;
|
||||
backdrop.click();
|
||||
|
||||
expect(overlayContainerElement.querySelector('md-dialog-container')).toBeTruthy();
|
||||
|
||||
dialogRef.disableClose = false;
|
||||
backdrop.click();
|
||||
|
||||
viewContainerFixture.detectChanges();
|
||||
viewContainerFixture.whenStable().then(() => {
|
||||
expect(overlayContainerElement.querySelector('md-dialog-container')).toBeFalsy();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
describe('hasBackdrop option', () => {
|
||||
|
||||
@@ -16,7 +16,6 @@ import {MdDialogConfig} from './dialog-config';
|
||||
import {MdDialogRef} from './dialog-ref';
|
||||
import {MdDialogContainer} from './dialog-container';
|
||||
import {TemplatePortal} from '../core/portal/portal';
|
||||
import 'rxjs/add/operator/first';
|
||||
|
||||
|
||||
/**
|
||||
@@ -147,7 +146,7 @@ export class MdDialog {
|
||||
let containerPortal = new ComponentPortal(MdDialogContainer, viewContainer);
|
||||
|
||||
let containerRef: ComponentRef<MdDialogContainer> = overlay.attach(containerPortal);
|
||||
containerRef.instance.dialogConfig = config;
|
||||
containerRef.instance.config = config;
|
||||
|
||||
return containerRef.instance;
|
||||
}
|
||||
@@ -166,14 +165,18 @@ export class MdDialog {
|
||||
dialogContainer: MdDialogContainer,
|
||||
overlayRef: OverlayRef,
|
||||
config: MdDialogConfig): MdDialogRef<T> {
|
||||
|
||||
// Create a reference to the dialog we're creating in order to give the user a handle
|
||||
// to modify and close it.
|
||||
|
||||
let dialogRef = new MdDialogRef<T>(overlayRef, dialogContainer);
|
||||
|
||||
if (!config.disableClose) {
|
||||
// When the dialog backdrop is clicked, we want to close it.
|
||||
overlayRef.backdropClick().first().subscribe(() => dialogRef.close());
|
||||
// When the dialog backdrop is clicked, we want to close it.
|
||||
if (config.hasBackdrop) {
|
||||
overlayRef.backdropClick().subscribe(() => {
|
||||
if (!dialogRef.disableClose) {
|
||||
dialogRef.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// We create an injector specifically for the component we're instantiating so that it can
|
||||
@@ -221,7 +224,7 @@ export class MdDialog {
|
||||
*/
|
||||
private _handleKeydown(event: KeyboardEvent): void {
|
||||
let topDialog = this._openDialogs[this._openDialogs.length - 1];
|
||||
let canClose = topDialog ? !topDialog._containerInstance.dialogConfig.disableClose : false;
|
||||
let canClose = topDialog ? !topDialog.disableClose : false;
|
||||
|
||||
if (event.keyCode === ESCAPE && canClose) {
|
||||
topDialog.close();
|
||||
|
||||
Reference in New Issue
Block a user