Variable de referencia de plantilla dinámica dentro de ngFor (Angular 9)

97

¿Cómo declarar una variable de referencia de plantilla dinámica dentro de un elemento?ngFor

Quiero usar el componente popover de ng-bootstrap, el código popover (con enlace Html) es como se muestra:

<ng-template #popContent>Hello, <b>{{name}}</b>!</ng-template>
<button type="button" class="btn btn-secondary" [ngbPopover]="popContent" popoverTitle="Fancy content">
    I've got markup and bindings in my popover!
</button>

¿Cómo puedo envolver esos elementos dentro ngFor?

<div *ngFor="let member of members">
    <!-- how to declare the '????' -->
    <ng-template #????>Hello, <b>{{member.name}}</b>!</ng-template>
        <button type="button" class="btn btn-secondary" [ngbPopover]="????" popoverTitle="Fancy content">
        I've got markup and bindings in my popover!
    </button>
</div>

Hmmm ... ¿alguna idea?

Boo Yan Jiong
fuente
No existen las variables de referencia dinámicas. ¿Por qué crees que debe ser dinámico?
Günter Zöchbauer
porque su tutorial decía que para tener un enlace html dentro de un popover, entonces necesitamos crear un ng-templatey referirlo con una variable de referencia de plantilla , pero ahora quiero usar este popover dentro de un ngForelemento
Boo Yan Jiong
8
Solo haz lo mismo. La variable de plantilla será diferente para cada elemento incluso cuando tenga el mismo nombre.
Günter Zöchbauer
3
¿Qué pasa si usas la misma referencia para todo? ¿Lo has probado?
developer033
Ja, nunca pienso en eso ... Lo probaré ahora ... porque sigo pensando en cómo declarar una ** variable de referencia de plantilla con "índice" ** ... se actualizará más tarde después de probarlo. ..: D
Boo Yan Jiong

Respuestas:

99

Las variables de referencia de plantilla tienen como ámbito la plantilla en la que están definidas. Una directiva estructural crea una plantilla anidada y, por lo tanto, introduce un ámbito separado.

Entonces puede usar una variable para la referencia de su plantilla

<div *ngFor="let member of members">
  <ng-template #popupContent>Hello, <b>{{member.name}}</b>!</ng-template>
  <button type="button" class="btn btn-secondary" [ngbPopover]="popupContent" popoverTitle="Fancy content">
      I've got markup and bindings in my popover!
  </button>
</div>

y debería funcionar porque ya ha declarado dentro <ng-template ngFor

Ejemplo de plunker

Para obtener más detalles, consulte también:

yurzui
fuente
1
Tenga en cuenta que si está usando un @ViewChild, no puede usar esta solución (y luego debe usar el de @ AlexBoisselle)
Aleatorio
17

Esta es la mejor solución que he encontrado: https://stackoverflow.com/a/40165639/3870815

En esa respuesta usan:

@ViewChildren('popContent') components:QueryList<CustomComponent>;

Para construir una lista de esos componentes generados dinámicamente. ¡Te recomiendo que lo pruebes!

Alex Boisselle
fuente
1
¡La mejor respuesta!
igg
1

Otra forma de permitir esto es crear un componente que envuelva el botón y la plantilla ng

<div *ngFor="let member of members">
    <popover-button [member]="member"></pop-over-button>
</div>

Y tenga lo siguiente en el componente de botón de popover

<ng-template #popContent>Hello, <b>{{member.name}}</b>!</ng-template>
    <button type="button" class="btn btn-secondary" [ngbPopover]="popContent" popoverTitle="Fancy content">
    I've got markup and bindings in my popover!
</button>
usuario14002866
fuente
-1

Puedes usar trackBy: trackByFnen*ngFor

<div *ngFor="let member of members;trackBy: trackByF">
    <ng-template #popupContent>Hello, <b>{{member.name}}</b>!</ng-template>
        <button type="button" class="btn btn-secondary" [ngbPopover]="popupContent" popoverTitle="Fancy content">
        I've got markup and bindings in my popover!
    </button>
</div>
Babak irannezhad
fuente