3
3
ComponentFactory , ComponentFactoryResolver , ComponentRef ,
4
4
Directive , Inject , InjectionToken , Injector ,
5
5
OnDestroy , EventEmitter , Output ,
6
- Type , ViewContainerRef , ElementRef
6
+ Type , ViewContainerRef , ElementRef , InjectFlags
7
7
} from "@angular/core" ;
8
8
import {
9
9
ActivatedRoute ,
@@ -19,7 +19,7 @@ import { profile } from "tns-core-modules/profiling";
19
19
20
20
import { BehaviorSubject } from "rxjs" ;
21
21
22
- import { DEVICE , PAGE_FACTORY , PageFactory } from "../platform-providers" ;
22
+ import { DEVICE , PAGE_FACTORY , PageFactory , PageService } from "../platform-providers" ;
23
23
import { routerLog as log , routerError as error , isLogEnabled } from "../trace" ;
24
24
import { DetachedLoader } from "../common/detached-loader" ;
25
25
import { ViewUtil } from "../view-util" ;
@@ -48,23 +48,28 @@ export function destroyComponentRef(componentRef: ComponentRef<any>) {
48
48
}
49
49
}
50
50
51
- class ChildInjector implements Injector {
52
- constructor (
53
- private providers : ProviderMap ,
54
- private parent : Injector
55
- ) { }
56
-
57
- get < T > ( token : Type < T > | InjectionToken < T > , notFoundValue ?: T ) : T {
58
- let localValue = this . providers . get ( token ) ;
59
- if ( localValue ) {
60
- return localValue ;
51
+ class DestructibleInjector implements Injector {
52
+ private refs = new Set < any > ( ) ;
53
+ constructor ( private destructableProviders : ProviderSet , private parent : Injector ) {
54
+ }
55
+ get < T > ( token : Type < T > | InjectionToken < T > , notFoundValue ?: T , flags ?: InjectFlags ) : T {
56
+ const ref = this . parent . get ( token , notFoundValue , flags ) ;
57
+ if ( this . destructableProviders . has ( token ) ) {
58
+ this . refs . add ( ref ) ;
61
59
}
62
-
63
- return this . parent . get ( token , notFoundValue ) ;
60
+ return ref ;
61
+ }
62
+ destroy ( ) {
63
+ this . refs . forEach ( ( ref ) => {
64
+ if ( ref . ngOnDestroy instanceof Function ) {
65
+ ref . ngOnDestroy ( ) ;
66
+ }
67
+ } ) ;
68
+ this . refs . clear ( ) ;
64
69
}
65
70
}
66
71
67
- type ProviderMap = Map < Type < any > | InjectionToken < any > , any > ;
72
+ type ProviderSet = Set < Type < any > | InjectionToken < any > > ;
68
73
69
74
/**
70
75
* There are cases where multiple activatedRoute nodes should be associated/handled by the same PageRouterOutlet.
@@ -335,16 +340,24 @@ export class PageRouterOutlet implements OnDestroy { // tslint:disable-line:dire
335
340
componentType : factory . componentType ,
336
341
} ) ;
337
342
338
- const providers = new Map ( ) ;
339
- providers . set ( Page , page ) ;
340
- providers . set ( Frame , this . frame ) ;
341
- providers . set ( PageRoute , new PageRoute ( activatedRoute ) ) ;
342
- providers . set ( ActivatedRoute , activatedRoute ) ;
343
- providers . set ( ChildrenOutletContexts , this . parentContexts . getOrCreateContext ( this . name ) . children ) ;
343
+ const destructables = new Set ( [ PageService ] ) ;
344
+ const injector = Injector . create ( {
345
+ providers : [
346
+ { provide : PageService , useClass : PageService , deps : [ Page ] } ,
347
+ { provide : Page , useValue : page } ,
348
+ { provide : Frame , useValue : this . frame } ,
349
+ { provide : PageRoute , useValue : new PageRoute ( activatedRoute ) } ,
350
+ { provide : ActivatedRoute , useValue : activatedRoute } ,
351
+ { provide : ChildrenOutletContexts ,
352
+ useValue : this . parentContexts . getOrCreateContext ( this . name ) . children }
353
+ ] ,
354
+ parent : this . location . injector
355
+ } ) ;
344
356
345
- const childInjector = new ChildInjector ( providers , this . location . injector ) ;
357
+ const childInjector = new DestructibleInjector ( destructables , injector ) ;
346
358
const loaderRef = this . location . createComponent (
347
359
this . detachedLoaderFactory , this . location . length , childInjector , [ ] ) ;
360
+ loaderRef . onDestroy ( ( ) => childInjector . destroy ( ) ) ;
348
361
this . changeDetector . markForCheck ( ) ;
349
362
350
363
this . activated = loaderRef . instance . loadWithFactory ( factory ) ;
0 commit comments