#angular
#угловатый
Вопрос:
я пытаюсь создать пользовательскую директиву всплывающей подсказки в angular, и я хочу передать TemplateRef в качестве входного свойства этой директиве из родительского компонента, но TemplateRef.ElementRef возвращает комментарий вместо содержимого шаблона.
Директива:
@Directive({
selector: '[tooltip]'
})
export class tooltipDirective {
@Input('tooltip') tooltip: ElementRef<any>;
@Input('placement') placement: string = 'bottom';
constructor(private el: ElementRef, private renderer: Renderer2) {
console.log(this.tooltip);
}
}
Родительский компонент:
<div [tooltip]="tooltipTemplate"> show tooltip </div>
<ng-template #tooltipTemplate>
<div class="tooltip">
tooltip text
</div>
</ng-template>
как я могу получить фактический контент?
Комментарии:
1. Не используйте конструктор (никогда.. действительно).. попробуйте использовать перехват AfterViewInit..
2. @MikeOne, Afterviewinit также дает тот же результат
3. Ах да .. извините. Я пропустил, что вы используете ввод, а не ViewChild.. честно говоря, не уверен, как это передать..
4. ок, нет проблем, спасибо за ваш ответ
Ответ №1:
вы можете использовать в геттере, но будьте осторожны, шаблон — это ссылка на шаблон. Если вы хотите добавить его, введите ViewContainerRef в конструктор, например:
_tooltip:TemplateRef<any>
@Input('tooltip') set tooltip(value)
{
this._tooltip=value
this.viewContainer.createEmbeddedView(this._tooltip)
}
@Input('placement') placement: string = 'bottom';
constructor(private viewContainer:ViewContainerRef) {}
Обновлено: Об использовании a this.viewContainer.createEmbeddedView(this._tooltip)
в целом мы делаем некоторые подобные
const embeddedViewRef = this.viewContainer.createEmbeddedView( this._tooltip );
embeddedViewRef.detectChanges(); //<--this makes that if our template
//has a variable and change, the tooltip
//take account this change
Затем, для создания инструмента, мы можем использовать Renderer2 для создания div и добавления в div всех узлов embeddedViewRef
const div = this.renderer.createElement("span");
embeddedViewRef.rootNodes.forEach(n => {
this.renderer.appendChild(div, n);
});
Ну, тяжелая работа — вычислить позицию, создать всплывающую подсказку класса и добавить два HostListener для mouseout и mouseover
Комментарии:
1. какова роль createEmbeddedView?
2. @jagjeet, я обновляю ответ, чтобы дать некоторую подсказку для создания всплывающей подсказки,
3. @Elison Большое спасибо, это идеально, есть только одна проблема, при таком подходе я не могу добавить контекст в шаблон при его использовании
4. я нашел решение для этого, используя вспомогательный компонент вместе с директивой, которую я обновлю здесь, если это сработает