У меня есть следующая директива и компоненты
TooltipDirective.ts
import { Directive, TemplateRef, Input, Type, ComponentRef, ElementRef,
Renderer2, Injector, ComponentFactoryResolver, ViewContainerRef,
HostListener, ReflectiveInjector } from '@angular/core';
import { TooltipComponent } from '../components/tooltip/tooltip.component';
@Directive({
selector: '[tooltip]'
})
export class TooltipDirective {
@Input('tooltip') content: string | TemplateRef<any> | Type<any>;
private componentRef: ComponentRef<TooltipComponent>;
constructor(private element: ElementRef,
private renderer: Renderer2,
private injector: Injector,
private resolver: ComponentFactoryResolver,
private vcr: ViewContainerRef) { }
@HostListener('mouseenter')
mouseenter() {
if (this.componentRef) return;
const factory = this.resolver.resolveComponentFactory(TooltipComponent);
const injector = ReflectiveInjector.resolveAndCreate([
{
provide: 'tooltipConfig',
useValue: {
host: this.element.nativeElement
}
}
]);
this.componentRef = this.vcr.createComponent(factory, 0, injector,
this.generateNgContent());
}
generateNgContent() {
if (typeof this.content === 'string') {
const element = this.renderer.createText(this.content);
return [[element]];
}
if (this.content instanceof TemplateRef) {
const context = {};
const viewRef = this.content.createEmbeddedView(context);
// In earlier versions, you may need to add this line
// this.appRef.attachView(viewRef);
return [viewRef.rootNodes];
}
// Else it's a component
const factory = this.resolver.resolveComponentFactory(this.content);
const componentRef = factory.create(this.injector);
// In earlier versions, you may need to add this line
// this.appRef.attachView(componentRef.hostView);
return [[componentRef.location.nativeElement]];
}
@HostListener('mouseout')
mouseout() {
this.destroy();
}
destroy() {
this.componentRef && this.componentRef.destroy();
this.componentRef = null;
}
ngOnDestroy() {
this.destroy();
}
}
tooltip.component.ts
import { Component, OnInit, Directive, ViewChild, ElementRef, Inject } from '@angular/core';
@Directive({
selector: '.tooltip-container'
})
export class TooltipContainerDirective {
}
@Component({
selector: 'yl-tooltip',
templateUrl: './tooltip.component.html',
styleUrls: ['./tooltip.component.scss']
})
export class TooltipComponent implements OnInit {
top : string;
@ViewChild(TooltipContainerDirective, { read: ElementRef }) private tooltipContainer;
constructor(@Inject('tooltipConfig') private config) { }
ngOnInit() {
// For simplicity, we calculate only the top.
const { top } = this.config.host.getBoundingClientRect();
const { height } = this.tooltipContainer.nativeElement.getBoundingClientRect();
this.top = `${top - height}px`;
}
}
tooltip.component.html
<div class="tooltip-container" [ngStyle]="{top: top}">
<ng-content></ng-content>
</div>
Я пытаюсь реализовать эту подсказку внутри * ngFor следующим образом:
<div *ngFor="let member of data">
<div [tooltip]="template"> This is user {{menber.Name}}</div>
<ng-template #template>
<div class="tooltip">
<div>{{member.Amount}}</div>
</div>
</ng-template>
</div>
Но подсказка не привязывает значение menber.Amount.Я использую шаблон, поскольку мне нужно сформировать всплывающую подсказку с пользовательским содержимым HTML. Чего мне здесь не хватает?