7
7
*/
8
8
9
9
import { CommonModule } from '@angular/common' ;
10
- import { ComponentFactory , EventEmitter , Host , Inject , Injectable , InjectionToken , Injector , NO_ERRORS_SCHEMA , NgModule , OnDestroy , ReflectiveInjector , SkipSelf } from '@angular/core' ;
10
+ import { Compiler , ComponentFactory , EventEmitter , Host , Inject , Injectable , InjectionToken , Injector , NO_ERRORS_SCHEMA , NgModule , NgModuleRef , OnDestroy , ReflectiveInjector , SkipSelf } from '@angular/core' ;
11
11
import { ChangeDetectionStrategy , ChangeDetectorRef , PipeTransform } from '@angular/core/src/change_detection/change_detection' ;
12
12
import { getDebugContext } from '@angular/core/src/errors' ;
13
13
import { ComponentFactoryResolver } from '@angular/core/src/linker/component_factory_resolver' ;
@@ -22,6 +22,7 @@ import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
22
22
import { DOCUMENT } from '@angular/platform-browser/src/dom/dom_tokens' ;
23
23
import { dispatchEvent , el } from '@angular/platform-browser/testing/src/browser_util' ;
24
24
import { expect } from '@angular/platform-browser/testing/src/matchers' ;
25
+
25
26
import { stringify } from '../../src/util' ;
26
27
27
28
const ANCHOR_ELEMENT = new InjectionToken ( 'AnchorElement' ) ;
@@ -1019,7 +1020,7 @@ function declareTests({useJit}: {useJit: boolean}) {
1019
1020
fixture . destroy ( ) ;
1020
1021
} ) ;
1021
1022
1022
- describe ( 'dynamic ViewContainers ' , ( ) => {
1023
+ describe ( 'ViewContainerRef.createComponent ' , ( ) => {
1023
1024
beforeEach ( ( ) => {
1024
1025
// we need a module to declarate ChildCompUsingService as an entryComponent otherwise the
1025
1026
// factory doesn't get created
@@ -1036,7 +1037,7 @@ function declareTests({useJit}: {useJit: boolean}) {
1036
1037
MyComp , { add : { template : '<div><dynamic-vp #dynamic></dynamic-vp></div>' } } ) ;
1037
1038
} ) ;
1038
1039
1039
- it ( 'should allow to create a ViewContainerRef at any bound location' , async ( ( ) => {
1040
+ it ( 'should allow to create a component at any bound location' , async ( ( ) => {
1040
1041
const fixture = TestBed . configureTestingModule ( { schemas : [ NO_ERRORS_SCHEMA ] } )
1041
1042
. createComponent ( MyComp ) ;
1042
1043
const tc = fixture . debugElement . children [ 0 ] . children [ 0 ] ;
@@ -1047,7 +1048,7 @@ function declareTests({useJit}: {useJit: boolean}) {
1047
1048
. toHaveText ( 'dynamic greet' ) ;
1048
1049
} ) ) ;
1049
1050
1050
- it ( 'should allow to create multiple ViewContainerRef at a location' , async ( ( ) => {
1051
+ it ( 'should allow to create multiple components at a location' , async ( ( ) => {
1051
1052
const fixture = TestBed . configureTestingModule ( { schemas : [ NO_ERRORS_SCHEMA ] } )
1052
1053
. createComponent ( MyComp ) ;
1053
1054
const tc = fixture . debugElement . children [ 0 ] . children [ 0 ] ;
@@ -1060,6 +1061,122 @@ function declareTests({useJit}: {useJit: boolean}) {
1060
1061
expect ( fixture . debugElement . children [ 0 ] . children [ 2 ] . nativeElement )
1061
1062
. toHaveText ( 'dynamic greet' ) ;
1062
1063
} ) ) ;
1064
+
1065
+ it ( 'should create a component that has been freshly compiled' , ( ) => {
1066
+ @Component ( { template : '' } )
1067
+ class RootComp {
1068
+ constructor ( public vc : ViewContainerRef ) { }
1069
+ }
1070
+
1071
+ @NgModule ( {
1072
+ declarations : [ RootComp ] ,
1073
+ providers : [ { provide : 'someToken' , useValue : 'someRootValue' } ] ,
1074
+ } )
1075
+ class RootModule {
1076
+ }
1077
+
1078
+ @Component ( { template : '' } )
1079
+ class MyComp {
1080
+ constructor ( @Inject ( 'someToken' ) public someToken : string ) { }
1081
+ }
1082
+
1083
+ @NgModule ( {
1084
+ declarations : [ MyComp ] ,
1085
+ providers : [ { provide : 'someToken' , useValue : 'someValue' } ] ,
1086
+ } )
1087
+ class MyModule {
1088
+ }
1089
+
1090
+ const compFixture =
1091
+ TestBed . configureTestingModule ( { imports : [ RootModule ] } ) . createComponent ( RootComp ) ;
1092
+ const compiler = < Compiler > TestBed . get ( Compiler ) ;
1093
+ const myCompFactory =
1094
+ < ComponentFactory < MyComp > > compiler . compileModuleAndAllComponentsSync ( MyModule )
1095
+ . componentFactories [ 0 ] ;
1096
+
1097
+ // Note: the ComponentFactory was created directly via the compiler, i.e. it
1098
+ // does not have an association to an NgModuleRef.
1099
+ // -> expect the providers of the module that the view container belongs to.
1100
+ const compRef = compFixture . componentInstance . vc . createComponent ( myCompFactory ) ;
1101
+ expect ( compRef . instance . someToken ) . toBe ( 'someRootValue' ) ;
1102
+ } ) ;
1103
+
1104
+ it ( 'should create a component with the passed NgModuleRef' , ( ) => {
1105
+ @Component ( { template : '' } )
1106
+ class RootComp {
1107
+ constructor ( public vc : ViewContainerRef ) { }
1108
+ }
1109
+
1110
+ @Component ( { template : '' } )
1111
+ class MyComp {
1112
+ constructor ( @Inject ( 'someToken' ) public someToken : string ) { }
1113
+ }
1114
+
1115
+ @NgModule ( {
1116
+ declarations : [ RootComp , MyComp ] ,
1117
+ entryComponents : [ MyComp ] ,
1118
+ providers : [ { provide : 'someToken' , useValue : 'someRootValue' } ] ,
1119
+ } )
1120
+ class RootModule {
1121
+ }
1122
+
1123
+ @NgModule ( { providers : [ { provide : 'someToken' , useValue : 'someValue' } ] } )
1124
+ class MyModule {
1125
+ }
1126
+
1127
+ const compFixture =
1128
+ TestBed . configureTestingModule ( { imports : [ RootModule ] } ) . createComponent ( RootComp ) ;
1129
+ const compiler = < Compiler > TestBed . get ( Compiler ) ;
1130
+ const myModule = compiler . compileModuleSync ( MyModule ) . create ( TestBed . get ( NgModuleRef ) ) ;
1131
+ const myCompFactory = ( < ComponentFactoryResolver > TestBed . get ( ComponentFactoryResolver ) )
1132
+ . resolveComponentFactory ( MyComp ) ;
1133
+
1134
+ // Note: MyComp was declared as entryComponent in the RootModule,
1135
+ // but we pass MyModule to the createComponent call.
1136
+ // -> expect the providers of MyModule!
1137
+ const compRef = compFixture . componentInstance . vc . createComponent (
1138
+ myCompFactory , undefined , undefined , undefined , myModule ) ;
1139
+ expect ( compRef . instance . someToken ) . toBe ( 'someValue' ) ;
1140
+ } ) ;
1141
+
1142
+ it ( 'should create a component with the NgModuleRef of the ComponentFactoryResolver' , ( ) => {
1143
+ @Component ( { template : '' } )
1144
+ class RootComp {
1145
+ constructor ( public vc : ViewContainerRef ) { }
1146
+ }
1147
+
1148
+ @NgModule ( {
1149
+ declarations : [ RootComp ] ,
1150
+ providers : [ { provide : 'someToken' , useValue : 'someRootValue' } ] ,
1151
+ } )
1152
+ class RootModule {
1153
+ }
1154
+
1155
+ @Component ( { template : '' } )
1156
+ class MyComp {
1157
+ constructor ( @Inject ( 'someToken' ) public someToken : string ) { }
1158
+ }
1159
+
1160
+ @NgModule ( {
1161
+ declarations : [ MyComp ] ,
1162
+ entryComponents : [ MyComp ] ,
1163
+ providers : [ { provide : 'someToken' , useValue : 'someValue' } ] ,
1164
+ } )
1165
+ class MyModule {
1166
+ }
1167
+
1168
+ const compFixture =
1169
+ TestBed . configureTestingModule ( { imports : [ RootModule ] } ) . createComponent ( RootComp ) ;
1170
+ const compiler = < Compiler > TestBed . get ( Compiler ) ;
1171
+ const myModule = compiler . compileModuleSync ( MyModule ) . create ( TestBed . get ( NgModuleRef ) ) ;
1172
+ const myCompFactory = myModule . componentFactoryResolver . resolveComponentFactory ( MyComp ) ;
1173
+
1174
+ // Note: MyComp was declared as entryComponent in MyModule,
1175
+ // and we don't pass an explicit ModuleRef to the createComponent call.
1176
+ // -> expect the providers of MyModule!
1177
+ const compRef = compFixture . componentInstance . vc . createComponent ( myCompFactory ) ;
1178
+ expect ( compRef . instance . someToken ) . toBe ( 'someValue' ) ;
1179
+ } ) ;
1063
1180
} ) ;
1064
1181
1065
1182
it ( 'should support static attributes' , ( ) => {
0 commit comments