Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 insert a @Component into the DOM of another component

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.

like image 573
Tarang Avatar asked Nov 12 '16 21:11

Tarang


People also ask

Can I import component in another component Angular?

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.

Can you create a component inside another component?

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.

How do you add one component to another component in Angular 12?

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.

How do you add components to other components?

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.


2 Answers

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);
  }
}
like image 101
yurzui Avatar answered Nov 03 '22 09:11

yurzui


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]
})
like image 41
brians69 Avatar answered Nov 03 '22 09:11

brians69