8

I could just do

<my-awesome-component *ngIf="ConditionToIncludeComponent"></my-awesome-component>

But every document on inserting component in dom dynamically is based on ViewContainerRef. I like what it does. But what makes it so special over *ngif?

Just point out pros and cons of both. Please. Thanks!

HDJEMAI
  • 9,436
  • 46
  • 67
  • 93
Prabesh
  • 353
  • 1
  • 6
  • 20

1 Answers1

16

TLDR;

If you don't know what component will be used in a component template when putting together this template use viewContainerRef. If you do know the component beforehand but it can sometimes be hidden, use ngIf.

Explanation

ViewContainerRef is used to specify the insertion point of the dynamic component. When using ngIf you need to specify the component in html in advance. So if you have a spot where you will insert one of three components you will need to do the following:

<my-awesome-component1 *ngIf="ConditionToIncludeComponent1"></my-awesome-component1>
<my-awesome-component2 *ngIf="ConditionToIncludeComponent2"></my-awesome-component2>
<my-awesome-component3 *ngIf="ConditionToIncludeComponent3"></my-awesome-component3>

Whereas with viewContainerRef you need only one spot (usually specified using `ng-container). Using ngComponentOutlet it can be done like this:

template: `<ng-container ngComponentOutlet="componentToInsert"></ng-container>`

class MyComponent {

   const myAwesomeComponent1 = cfr.resolveComponentFactory(MyAwesomeComponent1);
   const myAwesomeComponent2 = cfr.resolveComponentFactory(MyAwesomeComponent1);
   const myAwesomeComponent3 = cfr.resolveComponentFactory(MyAwesomeComponent1);
       
    if (ConditionToIncludeComponent1) {
        componentToInsert = myAwesomeComponent1;
    else if (ConditionToIncludeComponent2) {
        componentToInsert = myAwesomeComponent2;
    else if (ConditionToIncludeComponent3) {
        componentToInsert = myAwesomeComponent3;

Or component manually using createComponent method:

template: `<ng-container #spot></ng-container>`

class MyComponent {
   @ViewChild('spot', {read: ViewContainerRef}) vc;

   const myAwesomeComponent1 = cfr.resolveComponentFactory(MyAwesomeComponent1);
   const myAwesomeComponent2 = cfr.resolveComponentFactory(MyAwesomeComponent1);
   const myAwesomeComponent3 = cfr.resolveComponentFactory(MyAwesomeComponent1);
       
    if (ConditionToIncludeComponent1) {
        vc.createComponent(myAwesomeComponent1);
    else if (ConditionToIncludeComponent2) {
        vc.createComponent(myAwesomeComponent2);
    else if (ConditionToIncludeComponent3) {
        vc.createComponent(myAwesomeComponent3);

Besides inconvenience and a bloated html template the bigger problem with the ngIf approach is performance impact since three ngIf directives will have to perform some logic on each change detection cycle.

For more information read:

Community
  • 1
  • 1
Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488
  • Does that mean if I use ngIf, the component is already there but hidden? I will check your article for sure. Can you post another article on the topic of my question. I think lots of people on internet search for it. Thanks! – Prabesh Oct 10 '17 at 15:18
  • 2
    @Prabesh, no, `ngIf` will not create a component if it evaluates to `false`. But the instances of `ngIf` directives will be created. And Angular will be spending some time on each instance of `ngIf` during change detection. If you don't know what component will be used when putting together a component template. If you do know the component but it can sometimes be hidden, use `ngIf`. I'll think about the article suggestion, thanks – Max Koretskyi Oct 10 '17 at 15:31
  • I'm pretty sure I will be using ViewContainerRef from now on. thanks for putting time on my question. Currently, I want to create a comment section for pictures where top 5 comments will load after Comment button is clicked. and A comment box at last. Its obvious that i have to use ngFor for comments to load . So, how do you suggest should i combine ngFor and ViewContainerRef to make it work. And this means i need antoher for that comment box, right? – Prabesh Oct 10 '17 at 16:21
  • @Prabesh, can you please create another question an post a link here? – Max Koretskyi Oct 11 '17 at 04:54
  • @MaxWizardK Say, if i am showing a html table with multiple rows (generated using *ngFor), and show a tooltip component on hover of each row.So i should use *ngIf like `` , or i should use `viewcontainerRef` to insert this component dynamically on each hover on the `tr` tag. – Abhishek Kumar Oct 03 '18 at 07:17
  • @AbhishekKumar, I don't think there's a need here for dynamic components. This is what viewcontainerref for. – Max Koretskyi Oct 03 '18 at 14:15
  • @MaxWizardK thanks, then ngIF is better option as i have my component and its not a dynamic one. – Abhishek Kumar Oct 03 '18 at 14:16
  • @AbhishekKumar, yes, you know what component you want in advance. Read [this article](https://blog.angularindepth.com/here-is-what-you-need-to-know-about-dynamic-components-in-angular-ac1e96167f9e) to understand why we need dynamic components – Max Koretskyi Oct 03 '18 at 14:19