将 ng-content 的字符串输入直接渲染为 HTML
Posted
技术标签:
【中文标题】将 ng-content 的字符串输入直接渲染为 HTML【英文标题】:Render string input of ng-content directly as HTML 【发布时间】:2021-02-20 07:29:21 【问题描述】:组件是否可以接收在开始标签和结束标签之间传递给它的内容,并将输入直接分配给接收模板内的innerhtml
?
我有一个这样的string
输入:
public content: string =
'<div class="row">' +
' <div class="col">' +
' <h1>Friendly greetings!</h1>' +
' <p>' +
' This is my homepage..' +
' </p>' +
' </div>' +
'</div>';
并像这样把它放在我的组件中:
<app-content> content </app-content>
在app-content
里面我可以在模板中使用ng-content
来投影输入的内容。由于输入是string
,我只能看到string
,它所描述的HTML 元素不会被渲染。
我尝试注入 ElementRef
并通过 this.elementRef.nativeElement.textContent
访问文本节点,但必须先呈现内容才能以这种方式访问它。
当然,我可以像这样隐藏ng-content
生成的内容:
<div style="display: none">
<ng-content></ng-content>
</div>
然后在变量中获取textContent
(例如content
)并设置如下:
<div [outerHTML]="content"></div>
但这对我来说似乎很老套。
StackBlitz 项目:get-input-of-ng-content-directly
我错过了什么吗?
我想在模板中做这样的事情:<div [outerHTML]="incoming ng-content stuff"></div>
或者至少在组件构造函数中注入内容并将其设置为变量,但不先渲染内容只是为了隐藏它。
【问题讨论】:
我认为这是可能的,但是...为什么不将字符串(我猜是来自服务器的)传递给app-content
中的@Input()
?
又不想在父组件中做<app-content><div [outerHTML]="content"></div></app-content>
?
我对这个用例特别感兴趣,因为我想使用精益元素。没有额外的属性,没有辅助构造,只有标签之间的内容,然后直接访问它......没有上面描述的黑客。这似乎不像我想象的那样可能,但它绝对应该是。
@julianobrasil 你能详细说明这怎么可能吗?
Johannes,这与下面@tlm 的回答方向相同。除了那个答案,我只是绕过一些 Angular 的消毒剂,否则你将无法插入样式、类等以及传入的 HTML。
【参考方案1】:
我会说你有两个选择:
1.) @Input()
字段接收上面的content
,然后将content
呈现为innerHTML
,就像你提到的那样。所以像
<app-content [content]="content"></app-content>
然后你可以像上面的<div [innerHTML]=...
一样渲染你content
Input
2.) 或者您可以在 <app-content>
HTML 文件中使用 <ng-content>
,然后执行以下操作:
<app-content>
<div [innerHTML]="content"></div>
</app-content>
但是第二个选项可能假设 <app-content>
不是你的 Angular 应用程序的根元素。
【讨论】:
所以你认为直接访问标签之间的传入内容不是一种选择? @Johannes 如果我理解你想要正确做的事情,也许你可以尝试这样的事情:stackblitz.com/edit/… 我在组件ElementRef
上使用了 Renderer2
到 setProperty
,基于你上面提到的字符串属性。如果这是您的想法,我可以看到您还可以如何将该指令设为可跨组件重用的指令(并防止每个组件的 DI)。
请看我的StackBlitz project。目标是提供这样的传入内容:<app-content> content </app-content>
并在不隐藏的情况下获取它。以上是关于将 ng-content 的字符串输入直接渲染为 HTML的主要内容,如果未能解决你的问题,请参考以下文章
以编程方式将投影内容传递给儿童? (否则将呈现为 <ng-content> )