In Order to create dynamic listing the projected content are accessed using @ContentChild Directive. So, that when they are projected the "CONTEXT" should be used as of HOST || Parent component from where they have been called.
app-dynamic-list -> .ts file
@Input()
items: Array<any>;
@ContentChild('listItem', {static: false})
dynamicListTemplate: TemplateRef<any>;
app-dynamic-list -> .html file
<ng-container *ngFor="let item of items;">
<ng-container
[ngTemplateOutlet]="listItem"
[ngTemplateOutletContext]="{ item: item}">
</ng-container>
</<ng-container
So, When the the content are projected from parent component and the items are passed as @Input. Iterating each item and passing item object in item key which will be an object in this case and that item will be accessed using let-item in ng-template.
note: make sure @ContentChild('listItem'...) name should match with #listItem defined in parent component tag.
Therefore same template reference will be passed in [ngTemplateOutlet]="listItem" to tell angular which template to render dynamically as multiple templates can exist in host or child component.
<app-dynamic-list [items]="items">
// ContentChild Projected inside `app-dynamic-list` component
<ng-template #listItem let-item>
{{ item.id }} - {{ item.names.en }} ({{ item.names.np }})
</ng-template>
</app-dynamic-list>