How to Render Child Components Dynamically using loops if possible? (Angular 8)

I am trying to render my angular components dynamically using loops but I'm lost.

What I want to achieve is drag and re-arrange my components (I was able to achieve this using Dragula - ng2-dragula) but I want to save the arrangement to my local storage or session storage.

The tricky part is I am using child components

<section [dragula]="'VAMPIRES'">
    <div class="first_element_class" id="first_element">
       <my-first-component
       [outputData]="outputData"></my-first-component>
    </div>

    <div class="second_element_class" id="second_element">
       <my-second-component
       [outputData]="outputData"></my-second-component>
    </div>
</section>

I tried using the DOM sanitizer pipe to render them via for loops

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';

@Pipe({
    name: 'trustHtml'
})
export class TrustHtmlPipe implements PipeTransform  {    
   constructor(readonly sr: DomSanitizer){}  

   transform(html: string) : SafeHtml {
      return this.sr.bypassSecurityTrustHtml(html); 
   } 
} 

Updated HTML Code (Let's assume I added my html elements to an array of object)

objectHTML: any[] = [{ 
    toBeRender: `<div class="first_element_class" id="first_element">
       <my-first-component
       [outputData]="outputData"></my-first-component>
    </div>` 
}];

<section [dragula]="'VAMPIRES'">
    <div *ngFor="let element of objectHTML">
       <div [innerHTML]="element.toBeRender | trustHtml" ></div>
    </div>
</section>

My question is is it really possible to render the html child components/elements using ngFor? I tried using the DOMSanitizer but I'm only getting a blank page (No error on console)

Upvotes: 1

Views: 935

Answers (2)

Srijon Chakraborty
Srijon Chakraborty

Reputation: 2164

I have a similar solution for you. Firstly, in your <my-first-component> ts file declare "outputData" as @Input and use ngFor in HTML. Here is my sample code below.
CUSTOM Control
HTML: event.component.html

<h2>Event {{ event.id }}</h2>
<button (click)="event.hidden = true">Close me</button>


TS:event.component.ts

import { Component, Input } from '@angular/core';
import { Event } from './event';
@Component({
selector: 'my-event',
templateUrl: './event.component.html'
})
export class EventComponent  {
@Input() event: Event;
}
export interface Event 
{
id: number;  
hidden: boolean;
}

**HTML:** app.component.html (You can use that code where you need to.)
<button (click)="addEvent()">Add event</button>
<div *ngFor="let event of events">
   <my-event *ngIf="!event.hidden" [event]="event"></my-event>
</div>

Note: Here [event] is the @Input for your custom control and *ngFor is the loop.
TS: app.component.ts

import { Component } from '@angular/core';
import { Event } from './event';
@Component({
   selector: 'my-app',
   templateUrl: './app.component.html',
   styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
events: Array<Event> = [1, 2, 3, 4, 5].map(i => ({id: i, hidden: true}));
addEvent() {
    const event = this.events.find(e => e.hidden);
    if (event) {
    event.hidden = false;
    }
  }
}

Note: Please check the code and let me know. This code is also available in Stackblitz LINK .

Upvotes: 1

sonEtLumiere
sonEtLumiere

Reputation: 4562

You can iterate with ngFor and render many times the child component by his selector.

components = [1, 2, 3, 4, 5]; 
<ng-container *ngFor="let component of components">
   <child-component></child-component>
</ng-container>

Upvotes: 0

Related Questions