I have a component
import { Component } from '@angular/core';
@Component({
selector: 'test-component',
template: '<b>Content</b>',
})
export class TestPage {
constructor() {}
}
And I have another component:
import { Component } from '@angular/core';
@Component({
selector: 'main-component',
templateUrl: 'main.html',
})
export class MainPage {
constructor() {}
putInMyHtml() {
}
}
main.html:
<p>stuff</p>
<div> <!-- INSERT HERE --> </div>
How can I dynamically insert my TestPage
component into the area where <!--INSERT HERE-->
is programatically, like when I run putInMyHtml
.
I tried editing the DOM and inserting <test-component></test-component>
but it doesn't display the content text from TestPage's template.
I have a component
import { Component } from '@angular/core';
@Component({
selector: 'test-component',
template: '<b>Content</b>',
})
export class TestPage {
constructor() {}
}
And I have another component:
import { Component } from '@angular/core';
@Component({
selector: 'main-component',
templateUrl: 'main.html',
})
export class MainPage {
constructor() {}
putInMyHtml() {
}
}
main.html:
<p>stuff</p>
<div> <!-- INSERT HERE --> </div>
How can I dynamically insert my TestPage
component into the area where <!--INSERT HERE-->
is programatically, like when I run putInMyHtml
.
I tried editing the DOM and inserting <test-component></test-component>
but it doesn't display the content text from TestPage's template.
- Possible duplicate of Can't initialize dynamically appended (HTML) component in Angular 2 – eko Commented Nov 12, 2016 at 21:18
- That is the correct solution. Did you get an error message either in your browser console or your compiler? – Martin Commented Nov 12, 2016 at 21:19
- @Martin there isn't an error, it remains as <test-component> in the DOM without angular rendering the template. – Tarang Commented Nov 12, 2016 at 22:06
2 Answers
Reset to default 15Here's an Plunker Example with the ComponentFactoryResolver
Firstly you have to register your dynamic component TestPage
properly
app.module.ts
@NgModule({
declarations: [MainPage, TestPage],
entryComponents: [TestPage]
})
Alternative option
Declare dynamic-module.ts
import { NgModule, ANALYZE_FOR_ENTRY_COMPONENTS } from '@angular/core';
@NgModule({})
export class DynamicModule {
static withComponents(components: any[]) {
return {
ngModule: DynamicModule,
providers: [
{
provide: ANALYZE_FOR_ENTRY_COMPONENTS,
useValue: components,
multi: true
}
]
}
}
}
and import it in app.module.ts
@NgModule({
imports: [ BrowserModule, DynamicModule.withComponents([TestPage]) ],
declarations: [ MainComponent, TestPage ]
})
Then your MainPage
component might look as follows:
import { ViewChild, ViewContainerRef, ComponentFactoryResolver } from '@angular/core';
@Component({
selector: 'main-component',
template: `
<button (click)="putInMyHtml()">Insert component</button>
<p>stuff</p>
<div>
<template #target></template>
</div>
`
})
export class MainPage {
@ViewChild('target', { read: ViewContainerRef }) target: ViewContainerRef;
constructor(private cfr: ComponentFactoryResolver) {}
putInMyHtml() {
this.target.clear();
let compFactory = this.cfr.resolveComponentFactory(TestPage);
this.target.createComponent(compFactory);
}
}
If both components are in the same module, make sure they were both declared first:
MyModule
@NgModule({
declarations: [TestPage, MainComponent]
})
If they are in different modules, make sure you've exported TestPage
and imported it into the module where you load MainComponent
:
TestPageModule
@NgModule({
declarations: [TestPage],
exports: [TestPage]
})
MainComponent
@NgModule({
declarations: [MainComponent],
imports: [TestPage]
})