@@ -3,7 +3,6 @@ import type { BottomSheetOptions as MaterialBottomSheetOptions } from '@nativesc
3
3
import { AppHostView , DetachedLoader , once } from '@nativescript/angular' ;
4
4
import { LayoutBase , ProxyViewContainer , View } from '@nativescript/core' ;
5
5
import { Observable , Subject } from 'rxjs' ;
6
- import { filter , first , map } from 'rxjs/operators' ;
7
6
8
7
export type BaseShowBottomSheetOptions = Omit < MaterialBottomSheetOptions , 'closeCallback' | 'view' > ;
9
8
@@ -17,35 +16,36 @@ export class BottomSheetParams {
17
16
18
17
type ViewWithDialogRoot = View & { _ngDialogRoot ?: View } ;
19
18
19
+ interface SheetRef < TResult = unknown > {
20
+ detachedLoader ?: ComponentRef < DetachedLoader > ;
21
+ componentView ?: View ;
22
+ result : Subject < TResult > ;
23
+ }
24
+
20
25
@Injectable ( {
21
26
providedIn : 'root'
22
27
} )
23
28
export class BottomSheetService {
24
- private readonly results$ = new Subject < { sheetId : number ; result : any } > ( ) ;
25
-
26
- private detachedLoader : ComponentRef < DetachedLoader > ;
27
-
28
- private componentView : View ;
29
-
30
- private nextSheetId = 0 ;
31
-
32
- public show < T = any > ( type : Type < any > , options : BottomSheetOptions ) : Observable < T > {
29
+ public show < TResult = any > ( type : Type < any > , options : BottomSheetOptions ) : Observable < TResult > {
33
30
return this . showWithCloseCallback ( type , options ) . observable ;
34
31
}
35
32
36
- public showWithCloseCallback < T = any > ( type : Type < any > , options : BottomSheetOptions ) : { observable : Observable < T > ; closeCallback : ( ) => void } {
33
+ public showWithCloseCallback < TResult = any > ( type : Type < any > , options : BottomSheetOptions ) : { observable : Observable < TResult > ; closeCallback : ( ) => void } {
37
34
if ( ! options . viewContainerRef ) {
38
35
throw new Error ( 'No viewContainerRef: Make sure you pass viewContainerRef in BottomSheetOptions.' ) ;
39
36
}
40
37
41
- const sheetId = this . nextSheetId ++ ;
38
+ const sheetRef : SheetRef < TResult > = {
39
+ result : new Subject ( )
40
+ } ;
41
+
42
42
const parentView = this . getParentView ( options . viewContainerRef ) ;
43
43
const factoryResolver = this . getFactoryResolver ( options . viewContainerRef ) ;
44
- const bottomSheetParams = this . getBottomSheetParams ( options . context , sheetId ) ;
44
+ const bottomSheetParams = this . getBottomSheetParams ( options . context , sheetRef ) ;
45
45
46
- this . detachedLoader = this . createDetachedLoader ( factoryResolver , bottomSheetParams , options . viewContainerRef ) ;
46
+ sheetRef . detachedLoader = this . createDetachedLoader ( factoryResolver , bottomSheetParams , options . viewContainerRef ) ;
47
47
48
- this . loadComponent ( type ) . then ( ( componentView ) => {
48
+ this . loadComponent ( type , sheetRef ) . then ( ( componentView ) => {
49
49
parentView . showBottomSheet ( {
50
50
...options ,
51
51
...bottomSheetParams ,
@@ -54,11 +54,7 @@ export class BottomSheetService {
54
54
} ) ;
55
55
56
56
return {
57
- observable : this . results$ . pipe (
58
- filter ( ( item ) => item && item . sheetId === sheetId ) ,
59
- map ( ( item ) => item . result ) ,
60
- first ( )
61
- ) ,
57
+ observable : sheetRef . result ,
62
58
closeCallback : bottomSheetParams . closeCallback
63
59
} ;
64
60
}
@@ -98,18 +94,21 @@ export class BottomSheetService {
98
94
} ) ;
99
95
}
100
96
101
- private getBottomSheetParams ( context : any , sheetId : number ) : BottomSheetParams {
97
+ private getBottomSheetParams ( context : any , sheetRef : SheetRef ) : BottomSheetParams {
102
98
const closeCallback = once ( ( args ) => {
103
- this . results$ . next ( { result : args , sheetId } ) ;
99
+ const { result, componentView , detachedLoader } = sheetRef ;
104
100
105
- if ( ! this . componentView ) {
106
- return ;
107
- }
101
+ result . next ( args ) ;
102
+ result . complete ( ) ;
108
103
109
- this . componentView . closeBottomSheet ( ) ;
104
+ if ( componentView ) {
105
+ componentView . closeBottomSheet ( ) ;
106
+ }
110
107
111
- this . detachedLoader . instance . detectChanges ( ) ;
112
- this . detachedLoader . destroy ( ) ;
108
+ if ( detachedLoader ) {
109
+ detachedLoader . instance . detectChanges ( ) ;
110
+ detachedLoader . destroy ( ) ;
111
+ }
113
112
} ) ;
114
113
115
114
return new BottomSheetParams ( context , closeCallback ) ;
@@ -122,23 +121,23 @@ export class BottomSheetService {
122
121
return viewContainerRef . createComponent ( detachedLoaderFactory , 0 , childInjector , null ) ;
123
122
}
124
123
125
- private async loadComponent ( type : Type < any > ) : Promise < View > {
124
+ private async loadComponent ( type : Type < any > , sheetRef : SheetRef ) : Promise < View > {
126
125
try {
127
- const componentRef = await this . detachedLoader . instance . loadComponent ( type ) ;
126
+ const componentRef = await sheetRef . detachedLoader . instance . loadComponent ( type ) ;
128
127
const detachedProxy = componentRef . location . nativeElement as ProxyViewContainer ;
129
128
130
129
if ( detachedProxy . getChildrenCount ( ) > 1 ) {
131
130
throw new Error ( 'BottomSheet content has more than one root view.' ) ;
132
131
}
133
132
134
- this . componentView = detachedProxy . getChildAt ( 0 ) ;
133
+ sheetRef . componentView = detachedProxy . getChildAt ( 0 ) ;
135
134
136
- if ( this . componentView . parent instanceof LayoutBase ) {
137
- ( this . componentView . parent as ViewWithDialogRoot ) . _ngDialogRoot = this . componentView ;
138
- this . componentView . parent . removeChild ( this . componentView ) ;
135
+ if ( sheetRef . componentView . parent instanceof LayoutBase ) {
136
+ ( sheetRef . componentView . parent as ViewWithDialogRoot ) . _ngDialogRoot = sheetRef . componentView ;
137
+ sheetRef . componentView . parent . removeChild ( sheetRef . componentView ) ;
139
138
}
140
139
141
- return this . componentView ;
140
+ return sheetRef . componentView ;
142
141
} catch ( err ) {
143
142
console . error ( err ) ;
144
143
0 commit comments