2

I have a component A which only contain a div with an id and a buttons that renders a component inside the div using innterHTML document.getElementById('my-router-outlet').innerHTML = '<app-component-b-page></app-component-b-page>';. But this is not rendering I wonder why?.

I'm trying to avoid using ngIf to be a selector for which component should be rendered for performance reason. Also if I clear the innerHTML does the resources of that component will be cleared?

1
  • I think the answer provided by @Smokey could work. If you need more suggestions, it would be great if you can provide a demo . Also, when you say performance, can you be more specific. Commented Aug 15, 2019 at 5:50

2 Answers 2

1

Okay so a few things here

  1. innerHTML = '<app-component-b-page></app-component-b-page>' is never going to work, angular wont recognise the angular component tag from a innerHTML call

  2. using *ngIf wont affect the performance of the page, so doing the following

<app-component-b-page *ngIf="value === true"></app-component-b-page>

is probably you best option here

  1. If you really don't want to use *ngIf you can use @ViewChild and ComponentFactoryResolver

In your HTML

<!-- this is where your component will be rendered -->
<div #entry></div>

In your component

import { Component, OnInit, ViewChild, ViewContainerRef, ComponentFactoryResolver } from '@angular/core'
import { YourComponent } from ... // import the component you want to inject 
// ...

export class ...
  @ViewChild('entry', {read: ViewContainerRef, static: true }) entry: ViewContainerRef;

  constructor(
    private _resolver: ComponentFactoryResolver
  ) {}

  showComponent() {
     const factory = this._resolver.resolveComponentFactory(YourComponent);
     // this will insert your component onto the page
     const component = this.entry.createComponent(factory);
  }

  // and if you want to dynamically remove the created component you can do this

  removeComponent() {
     this.entry.clear();
  }

Sign up to request clarification or add additional context in comments.

3 Comments

This solution (option 3) assumes that the component has view children. How would I apply it if I'm working with a simple directive? I want to mark one of my DIVs with the directive custom and then, when a rodent action on it is recognized, I want to add a custom element. So: <div custom>Beep</div> and the in @HostListener("click")onClick(){}, I'd like to render in <app-icon-boink></app-icon-boink>. I want to believe that it's doable...
The specific hold-up of mine is that your suggestion assumes that I mark the target of the action with <div #entry> whereas I don't have that luxury. I'm getting the element injected: constructor(private element: ElementRef){} and can't manipulate it.
Also, it seems that ComponentFactoryResolver is obsoleted as of v13, it says. I'm sure the suggestion is still valid in an agnostic way, though. So my comment shouldn't be seen as a negative remark. Just an observation to future readers.
0

You are adding the element to the dom directly and it's not rendered by Angular. You should go for the *ngIf.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.