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.
You can put commonly used directives, pipes, and components into one module and then import just that module wherever you need it in other parts of your application. Notice the following: It imports the CommonModule because the module's component needs common directives.
It is totally fine to declare another Component in the same file, but declaring it inside another one's function would be inefficient. Imagine your app 'recreating' the second Component during each render . So, feel free to declare it in the same file, but don't do it inside another Component 's function.
if you want to insert HTML elements or other components in a component, then you do that using the concept of content projection. In Angular, you achieve content projection using < ng-content >< /ng-content >. You can make reusable components and scalable applications by properly using content projection.
1. Using selector as HTML tag. This is widely used way to include child component in other components and you might be already aware of this way. In this selector of child component is used in the parent component i.e. app component in this case, as normal HTML tag.
Here'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]
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With