gpt4 book ai didi

angular - 我可以从字符串创建 TemplateRef 吗?

转载 作者:行者123 更新时间:2023-12-04 11:08:54 27 4
gpt4 key购买 nike

我得到的组件

假设我有以下 super 简单的组件:

class MyComponent {
@Input()
simpleContent: string;
@ContentChild(TemplateRef)
content: TemplateRef<any>;
}

<div>
<div *ngIf="simpleContent; else complexContent">{{simpleContent}}</div>
<ng-template #complexContent>
<ng-container [ngTemplateOutlet]="content"></ng-container>
</ng-template>
</div>

根据用户的选择,它可以像这样使用:

<my-component simpleContent="Hello world!"></my-component>

或者它可以像这样使用:

<my-component>
<ng-template>Hello world!</ng-template>
</my-component>

虽然第二个选项允许嵌入 HTML 并因此更复杂的格式,但用户可以选择简单的方法,在大多数情况下只使用一个属性。



我想简化组件并去掉模板中的 if/else。我想象这样的事情:

class MyComponent {
@ContentChild(TemplateRef)
content: TemplateRef<any>;
@Input()
set simpleContent(value: string) {
this.content = new TemplateRef(value);
}
}

<div>
<ng-container [ngTemplateOutlet]="content"></ng-container>
</div>

显然这行不通,因为 new TemplateRef(value)不可能。

有没有办法在运行时动态创建一个基本的简单模板?

最佳答案

在这些示例中,我们实际上并没有“创建”templateRef,因为这需要 Angular 渲染器工厂和大量额外的代码来为新的 EmbeddedView 创建合适的注入(inject)器。我们只需要使用字符串值即时编辑模板,就可以了。
示例 1:使用 ng-container
使用 ng-container 扩展 OP 问题的模板 Markdown

<div>
<ng-container #container></ng-container>
</div>
<!-- Adding an empty template for later use -->
<ng-template #content><ng-content></ng-content></ng-template>
然后组件的代码看起来像这样
export class Component implements AfterViewInit{

@ViewChild("content") contentRef: TemplateRef<any>;
@ViewChild("container", {read: ViewContainerRef}) containerRef: ViewContainerRef;

divRef: HTMLElement;
value: string = "";
@Input()
set simpleContent(value: string) {
if(this.divRef){
this.divRef.innerHTML = this.value;
}
this.value = value;
}

constructor() {}

ngAfterViewInit(): void {
let div = document.createElement("div");
div.innerHTML = this.value;

var embeddedViewRef = this.contentRef.createEmbeddedView(this.containerRef);
this.containerRef.insert(embeddedViewRef);
embeddedViewRef.rootNodes[0].replaceWith(div);
this.divRef = div;
}
}
在这个例子中,我们获得了对位于 EmbeddedView 的 rootNodes 中的 ng-content 标签的引用,并将其替换为我们的原生 html 模板字符串。
示例 2:使用 elementRef
因为我们在第一个例子中注入(inject)了 nativeElements,我想为什么不直接编辑第一个 div 标签,通过 ViewChild 和 ElementRef 获取它的引用。
@Component({
selector: "component",
template:`<div #ref></div>`
})
export class Component implements AfterViewInit{

@ViewChild("ref", {read: ElementRef}) tref: ElementRef;

value: string = "";
@Input()
set simpleContent(value: string) {
if(this.tref) this.tref.nativeElement.innerHTML = this.value;
this.value = value;
}
constructor() {}
ngAfterViewInit(): void {
this.tref.nativeElement.innerHTML = this.value;
}
}
示例 3:使用简单的数据绑定(bind)
最后,既然它只是一个简单的字符串模板,我们想在组件中注入(inject)为什么不简单地使用 databinding内部HTML
@Component({
selector: "component",
template:`<div [innerHTML]="value"></div>`
})
export class Component{
value: string = "";
@Input()
set simpleContent(value: string) {
this.value = value;
}
constructor() {}

}

将近 2 年后,我怀疑 OP 仍在等待答案。这个回复对我来说主要是一个挑战,但我自己在研究中学到了一些东西。喜欢这篇关于 dom manipulation techniques in angular的文章
希望这对那里的人有用

关于angular - 我可以从字符串创建 TemplateRef 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54967339/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com