Skip to content

Commit ad3e47c

Browse files
authored
fix: modal beforeClosed and afterClosed consistency between platforms (#87)
1 parent 3758758 commit ad3e47c

File tree

4 files changed

+23
-12
lines changed

4 files changed

+23
-12
lines changed

packages/angular/src/lib/cdk/dialog/dialog-ref.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,14 @@ export class NativeDialogRef<T, R = any> {
6161
.subscribe(() => {
6262
clearTimeout(this._closeFallbackTimeout);
6363
this._finishDialogClose();
64+
this._afterClosed.next(this._result);
65+
this._afterClosed.complete();
6466
});
6567

6668
_nativeModalRef.onDismiss.subscribe(() => {
6769
this._beforeClosed.next(this._result);
6870
this._beforeClosed.complete();
69-
this._afterClosed.next(this._result);
70-
this._afterClosed.complete();
71+
7172
this.componentInstance = null!;
7273
_nativeModalRef.dispose();
7374
});
@@ -98,7 +99,11 @@ export class NativeDialogRef<T, R = any> {
9899
// amount of time plus 100ms. We don't need to run this outside the NgZone, because for the
99100
// vast majority of cases the timeout will have been cleared before it has the chance to fire.
100101
this._closeFallbackTimeout = setTimeout(
101-
() => this._finishDialogClose(),
102+
() => {
103+
this._finishDialogClose();
104+
this._afterClosed.next(this._result);
105+
this._afterClosed.complete();
106+
},
102107
//event.totalTime + 100);
103108
100
104109
);

packages/angular/src/lib/cdk/dialog/native-modal-ref.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export class NativeModalRef {
2222
modalViewRef: NgViewRef<any>;
2323

2424
private _closeCallback: () => void;
25+
private _isDismissed = false;
2526

2627
constructor(private _config: NativeDialogConfig, private _injector: Injector, @Optional() private location?: NSLocationStrategy) {
2728
let parentView = this._config.viewContainerRef?.element.nativeElement || Application.getRootView();
@@ -38,10 +39,12 @@ export class NativeModalRef {
3839
}
3940
this.parentView = parentView;
4041

41-
this._closeCallback = once(() => {
42+
this._closeCallback = once(async () => {
4243
this.stateChanged.next({ state: 'closing' });
43-
this.modalViewRef.firstNativeLikeView?.closeModal();
44-
this.location?._closeModalNavigation();
44+
if (!this._isDismissed) {
45+
this.modalViewRef.firstNativeLikeView?.closeModal();
46+
}
47+
await this.location?._closeModalNavigation();
4548
// this.detachedLoaderRef?.destroy();
4649
if (this.modalViewRef?.firstNativeLikeView.isLoaded) {
4750
fromEvent(this.modalViewRef.firstNativeLikeView, 'unloaded')
@@ -81,8 +84,8 @@ export class NativeModalRef {
8184
this.parentView.showModal(this.modalViewRef.firstNativeLikeView, {
8285
context: null,
8386
...userOptions,
84-
closeCallback: () => {
85-
this.location?._closeModalNavigation();
87+
closeCallback: async () => {
88+
await this.location?._closeModalNavigation();
8689
this.onDismiss.next();
8790
this.onDismiss.complete();
8891
},
@@ -113,8 +116,9 @@ export class NativeModalRef {
113116
this.parentView.showModal(this.modalViewRef.firstNativeLikeView, {
114117
context: null,
115118
...userOptions,
116-
closeCallback: () => {
117-
this.location?._closeModalNavigation();
119+
closeCallback: async () => {
120+
this._isDismissed = true;
121+
this._closeCallback(); // close callback can only be called once, so we call it here to setup the exit events
118122
this.onDismiss.next();
119123
this.onDismiss.complete();
120124
},

packages/angular/src/lib/legacy/directives/dialogs.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,15 @@ export class ModalDialogService {
123123
let detachedLoaderRef: ComponentRef<DetachedLoader>;
124124
let portalOutlet: NativeScriptDomPortalOutlet;
125125

126-
const closeCallback = once((...args) => {
126+
const closeCallback = once(async (...args) => {
127127
options.doneCallback.apply(undefined, args);
128128
if (componentViewRef) {
129129
componentViewRef.firstNativeLikeView.closeModal();
130130
const params = this.openedModalParams.pop();
131131
if (this._closed$) {
132132
this._closed$.next(params);
133133
}
134-
this.location._closeModalNavigation();
134+
await this.location._closeModalNavigation();
135135
if (detachedLoaderRef || portalOutlet) {
136136
this.zone.run(() => {
137137
portalOutlet?.dispose();

packages/angular/src/lib/legacy/router/ns-location-strategy.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,8 @@ export class NSLocationStrategy extends LocationStrategy {
354354
this.currentOutlet = outlet;
355355
this.currentOutlet.showingModal = false;
356356
this.callPopState(this.currentOutlet.peekState(), false);
357+
// this is needed because angular does a setTimeout on onPopState, so if we don't do this we might end up with inconsistent state
358+
return new Promise((resolve) => setTimeout(resolve, 0));
357359
}
358360
}
359361

0 commit comments

Comments
 (0)