Trying to place a component dynamically to a child element, using a directive.
The component (as template):
@Component({
selector: 'ps-tooltip',
template: `
<div class="ps-tooltip">
<div class="ps-tooltip-content">
<span>{{content}}</span>
</div>
</div>
`
})
export class TooltipComponent {
@Input()
content: string;
}
the directive:
import { TooltipComponent } from './tooltip.component';
@Directive({
selector: '[ps-tooltip]',
})
export class TooltipDirective implements AfterViewInit {
@Input('ps-tooltip') content: string;
private tooltip: ComponentRef<TooltipComponent>;
constructor(
private viewContainerRef: ViewContainerRef,
private resolver: ComponentFactoryResolver,
private elRef: ElementRef,
private renderer: Renderer
) { }
ngAfterViewInit() {
// add trigger class to el
this.renderer.setElementClass(this.elRef.nativeElement, 'ps-tooltip-trigger', true); // ok
// factory comp resolver
let factory = this.resolver.resolveComponentFactory(TooltipComponent);
// create component
this.tooltip = this.viewContainerRef.createComponent(factory);
console.log(this.tooltip);
// set content of the component
this.tooltip.instance.content = this.content as string;
}
}
The problem is that this is creating a sibling and I want a child (see bellow)
result:
<a class="ps-btn ps-tooltip-trigger" ng-reflect-content="the tooltip">
<span>Button</span>
</a>
<ps-tooltip>...</ps-tooltip>
wanted result:
<a class="ps-btn ps-tooltip-trigger" ng-reflect-content="the tooltip">
<span>Button</span>
<ps-tooltip>...</ps-tooltip>
</a>
Thanks in advance for your help!
Even dynamic component is inserted as sibling element you can still move element to desired place by using:
this.elRef.nativeElement.appendChild(this.tooltip.location.nativeElement);
Plunker Example
A better approach would be to have a nested ng-template
with template reference variable on it such that the component is added as a sibling to ng-template
but is now child to ng-template
's parent.
Your template should be
<div class="ps-tooltip">
<div class="ps-tooltip-content">
<span>{{content}}</span>
<ng-template #addHere></ng-template>
</div>
</div>
And in your component
@ViewChild('addHere') addHere: ViewContainerRef;
ngAfterViewInit() {
...
this.tooltip = addHere.createComponent(factory)
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With