33 ComponentFactory , ComponentFactoryResolver , ComponentRef ,
44 Directive , Inject , InjectionToken , Injector ,
55 OnDestroy , EventEmitter , Output ,
6- Type , ViewContainerRef , ElementRef
6+ Type , ViewContainerRef , ElementRef , InjectFlags
77} from "@angular/core" ;
88import {
99 ActivatedRoute ,
@@ -19,7 +19,7 @@ import { profile } from "tns-core-modules/profiling";
1919
2020import { BehaviorSubject } from "rxjs" ;
2121
22- import { DEVICE , PAGE_FACTORY , PageFactory } from "../platform-providers" ;
22+ import { DEVICE , PAGE_FACTORY , PageFactory , PageService } from "../platform-providers" ;
2323import { routerLog as log , routerError as error , isLogEnabled } from "../trace" ;
2424import { DetachedLoader } from "../common/detached-loader" ;
2525import { ViewUtil } from "../view-util" ;
@@ -48,23 +48,28 @@ export function destroyComponentRef(componentRef: ComponentRef<any>) {
4848 }
4949}
5050
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 ) ;
6159 }
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 ( ) ;
6469 }
6570}
6671
67- type ProviderMap = Map < Type < any > | InjectionToken < any > , any > ;
72+ type ProviderSet = Set < Type < any > | InjectionToken < any > > ;
6873
6974/**
7075 * 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
335340 componentType : factory . componentType ,
336341 } ) ;
337342
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+ } ) ;
344356
345- const childInjector = new ChildInjector ( providers , this . location . injector ) ;
357+ const childInjector = new DestructibleInjector ( destructables , injector ) ;
346358 const loaderRef = this . location . createComponent (
347359 this . detachedLoaderFactory , this . location . length , childInjector , [ ] ) ;
360+ loaderRef . onDestroy ( ( ) => childInjector . destroy ( ) ) ;
348361 this . changeDetector . markForCheck ( ) ;
349362
350363 this . activated = loaderRef . instance . loadWithFactory ( factory ) ;
0 commit comments