0

I have created a wrapping component that takes <div *ngFor='let item of items> as projected content.

I want to replace the immediate bindings of the projected content, with that of the wrapping component.

I am aware that with *ngTemplateOutlet I can define a associated context object. But I don't know how this can be of use.

Note: The projected content need not be a div, but it must be an element that supports *ngFor.

    Component({
      selector: 'some-component',
      template: `
          <wrapper>
            <div *ngFor="let item of items" <-- make items refer to items in wrapper and not some-component">
<span>{{item}}</span>
</div>
           <wrapper>
      `
    })
    class SomeComponent{
      items = ['text 1'] <-- replace this ngFor binding
    }


    Component({
      selector: 'wrapper',
      template: `
          <ng-content></ng-content>
      `
    })
    class Wrapper {
      items = ['text 2'] <-- bind ngFor items to this member
    }

I expect the span to display 'text 2' not 'text 1'.

@MartinSchneider - Modified example

@Component({
  selector: 'my-wrapper',
  template: `
    <ng-container *ngFor="let item of items">
      <ng-content *ngTemplateOutlet="myItemTmpl, context: { $implicit: items}"></ng-content>
    </ng-container>
  `
})
export class MyWrapperComponent {
  @ContentChild('myItem', {static: false}) myItemTmpl: TemplateRef<any>; 

  items = [
    { id: 0, name: "foo"},
    { id: 1, name: "bar"}
  ];

}

<my-wrapper>
  <div *ngFor="let item of items" #myItem let-items>
    <h3>{{item.name}}</h3>
    <p>ID: {{item.id}}</p>
  </ng-template>
</my-wrapper>
Will
  • 521
  • 1
  • 6
  • 18
  • 1
    I am pretty sure that this is not possible or I didn't understand it correctly. You should provide a better example with the outcome you want. – Dino Jul 19 '19 at 15:10
  • 1
    AFAIK, you can't do that. But you can put the loop inside the wrapper component template, and repeat an ng-template passed from the outside. You could take inspiration from the tabset or the accordion component of ng-bootstrap: See https://github.com/ng-bootstrap/ng-bootstrap/blob/master/src/tabset/tabset.ts and https://ng-bootstrap.github.io/#/components/tabset/examples for example usage. – JB Nizet Jul 19 '19 at 15:11

1 Answers1

1

Is it similar to that issue:
How to render multiple ng-content inside an ngFor loop using Angular 4?
?

So, something like this:

import { Component, ContentChild, TemplateRef } from '@angular/core';

@Component({
  selector: 'my-wrapper',
  template: `
    <ng-container *ngFor="let item of items">
      <ng-container *ngTemplateOutlet="myItemTmpl, context: { $implicit: item }"></ng-container>
    </ng-container>
  `
})
export class MyWrapperComponent {
  @ContentChild('myItem', {static: false}) myItemTmpl: TemplateRef<any>; 

  items = [
    { id: 0, name: "foo"},
    { id: 1, name: "bar"}
  ];

}
<my-wrapper>
  <ng-template #myItem let-item>
    <h3>{{item.name}}</h3>
    <p>ID: {{item.id}}</p>
  </ng-template>
</my-wrapper>
Martin Schneider
  • 14,263
  • 7
  • 55
  • 58
  • Yes! I added an update to the OP and modified your example. Would something like that work? – Will Jul 19 '19 at 16:28