angular - Send et ng-template-element til en direktiv
Jeg prøver å sende et ng-template til direktivet mitt, noe slikt som dette:
komponent.html
<div myDirective [myTemplate]="myTemplate"></div>
<ng-template #myTemplate><p>Lorem ipsum dolor sit amet.</p></ng-template>
directive.ts
import {Directive, Input} from "@angular/core"
@Directive({
selector: "[myDirective]"
})
export class MyDirective {
@Input() myTemplate
ngOnInit () {
console.log(this.myTemplate.elementRef.nativeElement)
}
}
Men det viser bare <!-- -->. Hvordan får jeg tilgang til innholdet i malen? Ingen av de andre egenskapene ser ut til å ha det - kommentarer på dette spørsmålet foreslår å bruke templateRef i stedet, men det er udefinert.
Stackblitz om nødvendig.
For å klargjøre, er det endelige målet med direktivet å betinget legge til innholdet i malen til dens overordnede element (sammen med noen andre endringer).
Svar #1
Som du kan se på angular.io :
Ng-template er et Angular-element for å gjengi HTML. Det vises aldri direkte. Faktisk, før visningen gjengis, erstatter Angular ng-template og innholdet med en kommentar.
Så ved kjøretid er ng-template bare en kommentar. Den kan ikke rendres som en DOM, og det er umulig å nå den som ElementRef-typen.
Men hvis du for eksempel vil sende et p-element til direktivet ditt, er det mulig. Jeg endret koden din for å gjøre det. Se dette Stackblitz-prosjektet:
https://stackblitz.com
Svar #2
Jeg har en popup-direktiv for å håndtere posisjonering av popup-vinduer i DOM-en. Jeg plasserer direktivet på en knapp eller lenke og sender det popup-elementet. Direktivet posisjonerer deretter popup-vinduet i DOM-en.
Direktivet støtter både et vanlig HTML-element og et ng-template-element som en popup.
For klarhetens skyld inneholder koden nedenfor bare deler som er relevante for spørsmålet.
import { Directive, ElementRef, Input, OnInit, TemplateRef, ViewContainerRef } from "@angular/core";
@Directive({
selector: '[ui-popup]'
})
export class UIPopupDirective implements OnInit, OnDestroy {
constructor(private el: ElementRef, private containerRef: ViewContainerRef) { }
@Input() popupTemplate: HTMLElement;
@Input() popupNgTemplate: TemplateRef<any>;
@Input() data:any;
ngOnInit() {
if (this.popupNgTemplate) {
const embeddedViewRef = this.containerRef.createEmbeddedView(this.popupNgTemplate, {
item: this.data
});
embeddedViewRef.detectChanges();
this.popupTemplate = embeddedViewRef.rootNodes[0];
}
}
Eksempler på bruk:
<button type="button" ui-popup [popupTemplate]="regularTag">Click to say hello</button>
<div #regularTag>Hello</div>
... eller ...
<button type="button" ui-popup [popupNgTemplate]="ngTemplateTag">Click to discover the world</button>
<ng-template #ngTemplateTag><div>World</div></ng-template>
