Why adding a Material Module breaks the dynamic component insertion?
up vote
1
down vote
favorite
Here are two MCVEs on StackBlitz using dynamic component creation. I would like to understand why :
This works.- But this does not work, just after importing a Material Module (
MatButtonModule
) into the dynamically created module.
Does anyone have an idea?
Example that works
app.component.ts
import { Component, ChangeDetectionStrategy, OnDestroy, ChangeDetectorRef, ViewChild, ViewContainerRef, Input, Compiler, Injector, NgModuleRef, SimpleChanges, NgModule, ComponentFactoryResolver, ReflectiveInjector } from '@angular/core';
import { CommonModule } from '@angular/common';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule } from '@angular/common/http';
import { MatButtonModule } from '@angular/material';
@Component({
selector: 'my-app',
template: `
<ng-container
#viewContainerRef
></ng-container>
`,
})
export class AppComponent {
@ViewChild('viewContainerRef', { read: ViewContainerRef }) viewContainerRef: ViewContainerRef;
constructor(
private compiler: Compiler,
private injector: Injector,
private ngModuleRef: NgModuleRef<any>,
private changeDetectorRef: ChangeDetectorRef,
) {
}
ngOnInit() {
const template = `
<button
mat-button
[innerHTML]="'Click me!'"
>
</button>
`
this.viewContainerRef.clear();
const component = Component({
changeDetection: ChangeDetectionStrategy.OnPush,
template
})(class { });
const ngModule = NgModule({
imports: [
CommonModule,
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
],
entryComponents: [component],
declarations: [component]
})(class { });
this.compiler.compileModuleAndAllComponentsAsync(ngModule).then((factories) => {
const factory = factories.componentFactories[0];
const componentRef = this.viewContainerRef.createComponent(
factory,
this.viewContainerRef.length,
this.injector,
,
this.ngModuleRef
);
this.changeDetectorRef.detectChanges();
});
}
}
app.module.ts
import { NgModule, CompilerFactory, COMPILER_OPTIONS, Compiler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { JitCompilerFactory } from '@angular/platform-browser-dynamic';
import { AppComponent } from './app.component';
export function createCompiler(compilerFactory: CompilerFactory) {
return compilerFactory.createCompiler();
}
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ],
providers: [
{ provide: COMPILER_OPTIONS, useValue: {}, multi: true },
{ provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS] },
{ provide: Compiler, useFactory: createCompiler, deps: [CompilerFactory] },
],
})
export class AppModule { }
Example that does not work
Adds the MatButtonModule
into the imports of the dynamic module :
app.component.ts
const ngModule = NgModule({
imports: [
CommonModule,
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
MatButtonModule,
],
entryComponents: [component],
declarations: [component]
})(class { });
Behavior
There are no errors, but the dynamic component seems to not be inserted (it is at least not visible).
angular angular-material2 ng-modules
add a comment |
up vote
1
down vote
favorite
Here are two MCVEs on StackBlitz using dynamic component creation. I would like to understand why :
This works.- But this does not work, just after importing a Material Module (
MatButtonModule
) into the dynamically created module.
Does anyone have an idea?
Example that works
app.component.ts
import { Component, ChangeDetectionStrategy, OnDestroy, ChangeDetectorRef, ViewChild, ViewContainerRef, Input, Compiler, Injector, NgModuleRef, SimpleChanges, NgModule, ComponentFactoryResolver, ReflectiveInjector } from '@angular/core';
import { CommonModule } from '@angular/common';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule } from '@angular/common/http';
import { MatButtonModule } from '@angular/material';
@Component({
selector: 'my-app',
template: `
<ng-container
#viewContainerRef
></ng-container>
`,
})
export class AppComponent {
@ViewChild('viewContainerRef', { read: ViewContainerRef }) viewContainerRef: ViewContainerRef;
constructor(
private compiler: Compiler,
private injector: Injector,
private ngModuleRef: NgModuleRef<any>,
private changeDetectorRef: ChangeDetectorRef,
) {
}
ngOnInit() {
const template = `
<button
mat-button
[innerHTML]="'Click me!'"
>
</button>
`
this.viewContainerRef.clear();
const component = Component({
changeDetection: ChangeDetectionStrategy.OnPush,
template
})(class { });
const ngModule = NgModule({
imports: [
CommonModule,
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
],
entryComponents: [component],
declarations: [component]
})(class { });
this.compiler.compileModuleAndAllComponentsAsync(ngModule).then((factories) => {
const factory = factories.componentFactories[0];
const componentRef = this.viewContainerRef.createComponent(
factory,
this.viewContainerRef.length,
this.injector,
,
this.ngModuleRef
);
this.changeDetectorRef.detectChanges();
});
}
}
app.module.ts
import { NgModule, CompilerFactory, COMPILER_OPTIONS, Compiler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { JitCompilerFactory } from '@angular/platform-browser-dynamic';
import { AppComponent } from './app.component';
export function createCompiler(compilerFactory: CompilerFactory) {
return compilerFactory.createCompiler();
}
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ],
providers: [
{ provide: COMPILER_OPTIONS, useValue: {}, multi: true },
{ provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS] },
{ provide: Compiler, useFactory: createCompiler, deps: [CompilerFactory] },
],
})
export class AppModule { }
Example that does not work
Adds the MatButtonModule
into the imports of the dynamic module :
app.component.ts
const ngModule = NgModule({
imports: [
CommonModule,
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
MatButtonModule,
],
entryComponents: [component],
declarations: [component]
})(class { });
Behavior
There are no errors, but the dynamic component seems to not be inserted (it is at least not visible).
angular angular-material2 ng-modules
that awkward moment a future reader looks at this and stackblitz is not available.
– Stavm
Nov 11 at 11:20
Thanks @Stavm, so I posted the code here too.
– Hadrien TOMA
Nov 11 at 11:21
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
Here are two MCVEs on StackBlitz using dynamic component creation. I would like to understand why :
This works.- But this does not work, just after importing a Material Module (
MatButtonModule
) into the dynamically created module.
Does anyone have an idea?
Example that works
app.component.ts
import { Component, ChangeDetectionStrategy, OnDestroy, ChangeDetectorRef, ViewChild, ViewContainerRef, Input, Compiler, Injector, NgModuleRef, SimpleChanges, NgModule, ComponentFactoryResolver, ReflectiveInjector } from '@angular/core';
import { CommonModule } from '@angular/common';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule } from '@angular/common/http';
import { MatButtonModule } from '@angular/material';
@Component({
selector: 'my-app',
template: `
<ng-container
#viewContainerRef
></ng-container>
`,
})
export class AppComponent {
@ViewChild('viewContainerRef', { read: ViewContainerRef }) viewContainerRef: ViewContainerRef;
constructor(
private compiler: Compiler,
private injector: Injector,
private ngModuleRef: NgModuleRef<any>,
private changeDetectorRef: ChangeDetectorRef,
) {
}
ngOnInit() {
const template = `
<button
mat-button
[innerHTML]="'Click me!'"
>
</button>
`
this.viewContainerRef.clear();
const component = Component({
changeDetection: ChangeDetectionStrategy.OnPush,
template
})(class { });
const ngModule = NgModule({
imports: [
CommonModule,
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
],
entryComponents: [component],
declarations: [component]
})(class { });
this.compiler.compileModuleAndAllComponentsAsync(ngModule).then((factories) => {
const factory = factories.componentFactories[0];
const componentRef = this.viewContainerRef.createComponent(
factory,
this.viewContainerRef.length,
this.injector,
,
this.ngModuleRef
);
this.changeDetectorRef.detectChanges();
});
}
}
app.module.ts
import { NgModule, CompilerFactory, COMPILER_OPTIONS, Compiler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { JitCompilerFactory } from '@angular/platform-browser-dynamic';
import { AppComponent } from './app.component';
export function createCompiler(compilerFactory: CompilerFactory) {
return compilerFactory.createCompiler();
}
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ],
providers: [
{ provide: COMPILER_OPTIONS, useValue: {}, multi: true },
{ provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS] },
{ provide: Compiler, useFactory: createCompiler, deps: [CompilerFactory] },
],
})
export class AppModule { }
Example that does not work
Adds the MatButtonModule
into the imports of the dynamic module :
app.component.ts
const ngModule = NgModule({
imports: [
CommonModule,
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
MatButtonModule,
],
entryComponents: [component],
declarations: [component]
})(class { });
Behavior
There are no errors, but the dynamic component seems to not be inserted (it is at least not visible).
angular angular-material2 ng-modules
Here are two MCVEs on StackBlitz using dynamic component creation. I would like to understand why :
This works.- But this does not work, just after importing a Material Module (
MatButtonModule
) into the dynamically created module.
Does anyone have an idea?
Example that works
app.component.ts
import { Component, ChangeDetectionStrategy, OnDestroy, ChangeDetectorRef, ViewChild, ViewContainerRef, Input, Compiler, Injector, NgModuleRef, SimpleChanges, NgModule, ComponentFactoryResolver, ReflectiveInjector } from '@angular/core';
import { CommonModule } from '@angular/common';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule } from '@angular/common/http';
import { MatButtonModule } from '@angular/material';
@Component({
selector: 'my-app',
template: `
<ng-container
#viewContainerRef
></ng-container>
`,
})
export class AppComponent {
@ViewChild('viewContainerRef', { read: ViewContainerRef }) viewContainerRef: ViewContainerRef;
constructor(
private compiler: Compiler,
private injector: Injector,
private ngModuleRef: NgModuleRef<any>,
private changeDetectorRef: ChangeDetectorRef,
) {
}
ngOnInit() {
const template = `
<button
mat-button
[innerHTML]="'Click me!'"
>
</button>
`
this.viewContainerRef.clear();
const component = Component({
changeDetection: ChangeDetectionStrategy.OnPush,
template
})(class { });
const ngModule = NgModule({
imports: [
CommonModule,
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
],
entryComponents: [component],
declarations: [component]
})(class { });
this.compiler.compileModuleAndAllComponentsAsync(ngModule).then((factories) => {
const factory = factories.componentFactories[0];
const componentRef = this.viewContainerRef.createComponent(
factory,
this.viewContainerRef.length,
this.injector,
,
this.ngModuleRef
);
this.changeDetectorRef.detectChanges();
});
}
}
app.module.ts
import { NgModule, CompilerFactory, COMPILER_OPTIONS, Compiler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { JitCompilerFactory } from '@angular/platform-browser-dynamic';
import { AppComponent } from './app.component';
export function createCompiler(compilerFactory: CompilerFactory) {
return compilerFactory.createCompiler();
}
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ],
providers: [
{ provide: COMPILER_OPTIONS, useValue: {}, multi: true },
{ provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS] },
{ provide: Compiler, useFactory: createCompiler, deps: [CompilerFactory] },
],
})
export class AppModule { }
Example that does not work
Adds the MatButtonModule
into the imports of the dynamic module :
app.component.ts
const ngModule = NgModule({
imports: [
CommonModule,
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
MatButtonModule,
],
entryComponents: [component],
declarations: [component]
})(class { });
Behavior
There are no errors, but the dynamic component seems to not be inserted (it is at least not visible).
angular angular-material2 ng-modules
angular angular-material2 ng-modules
edited Nov 11 at 11:32
asked Nov 11 at 10:22
Hadrien TOMA
7931120
7931120
that awkward moment a future reader looks at this and stackblitz is not available.
– Stavm
Nov 11 at 11:20
Thanks @Stavm, so I posted the code here too.
– Hadrien TOMA
Nov 11 at 11:21
add a comment |
that awkward moment a future reader looks at this and stackblitz is not available.
– Stavm
Nov 11 at 11:20
Thanks @Stavm, so I posted the code here too.
– Hadrien TOMA
Nov 11 at 11:21
that awkward moment a future reader looks at this and stackblitz is not available.
– Stavm
Nov 11 at 11:20
that awkward moment a future reader looks at this and stackblitz is not available.
– Stavm
Nov 11 at 11:20
Thanks @Stavm, so I posted the code here too.
– Hadrien TOMA
Nov 11 at 11:21
Thanks @Stavm, so I posted the code here too.
– Hadrien TOMA
Nov 11 at 11:21
add a comment |
1 Answer
1
active
oldest
votes
up vote
3
down vote
accepted
The reason for this is that you always take the first compiled factory from array.
const factory = factories.componentFactories[0];
while you need to get the factory from your component:
const factory = factories.componentFactories.find(x => x.componentType === component);
Perfect, thank you very much!
– Hadrien TOMA
Nov 11 at 11:45
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
The reason for this is that you always take the first compiled factory from array.
const factory = factories.componentFactories[0];
while you need to get the factory from your component:
const factory = factories.componentFactories.find(x => x.componentType === component);
Perfect, thank you very much!
– Hadrien TOMA
Nov 11 at 11:45
add a comment |
up vote
3
down vote
accepted
The reason for this is that you always take the first compiled factory from array.
const factory = factories.componentFactories[0];
while you need to get the factory from your component:
const factory = factories.componentFactories.find(x => x.componentType === component);
Perfect, thank you very much!
– Hadrien TOMA
Nov 11 at 11:45
add a comment |
up vote
3
down vote
accepted
up vote
3
down vote
accepted
The reason for this is that you always take the first compiled factory from array.
const factory = factories.componentFactories[0];
while you need to get the factory from your component:
const factory = factories.componentFactories.find(x => x.componentType === component);
The reason for this is that you always take the first compiled factory from array.
const factory = factories.componentFactories[0];
while you need to get the factory from your component:
const factory = factories.componentFactories.find(x => x.componentType === component);
answered Nov 11 at 11:42
yurzui
91.7k10180203
91.7k10180203
Perfect, thank you very much!
– Hadrien TOMA
Nov 11 at 11:45
add a comment |
Perfect, thank you very much!
– Hadrien TOMA
Nov 11 at 11:45
Perfect, thank you very much!
– Hadrien TOMA
Nov 11 at 11:45
Perfect, thank you very much!
– Hadrien TOMA
Nov 11 at 11:45
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53247787%2fwhy-adding-a-material-module-breaks-the-dynamic-component-insertion%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
that awkward moment a future reader looks at this and stackblitz is not available.
– Stavm
Nov 11 at 11:20
Thanks @Stavm, so I posted the code here too.
– Hadrien TOMA
Nov 11 at 11:21