Html 角度:使用ComponentFactoryResolver动态实例化组件,在SVG内部呈现
我有一个呈现DOM的组件,它应该位于Html 角度:使用ComponentFactoryResolver动态实例化组件,在SVG内部呈现,html,angular,svg,Html,Angular,Svg,我有一个呈现DOM的组件,它应该位于svg标记中: 从'@angular/core'导入{Component,Input}; @组成部分({ 选择器:“g[你好]”, 模板:`Hello,{{name}}`, 样式:[`h1{font-family:Lato;}`] }) 导出类HelloComponent{ @Input()名称:string; } 静态实例化时,一切正常(文本在页面上可见): 将生成以下DOM: 你好,静态组件 当我尝试使用ComponentFactoryResol
svg
标记中:
从'@angular/core'导入{Component,Input};
@组成部分({
选择器:“g[你好]”,
模板:`Hello,{{name}}`,
样式:[`h1{font-family:Lato;}`]
})
导出类HelloComponent{
@Input()名称:string;
}
静态实例化时,一切正常(文本在页面上可见):
将生成以下DOM:
你好,静态组件
当我尝试使用ComponentFactoryResolver动态实例化组件时,问题就出现了:
import{Component,ViewChild,ViewContainerRef,ComponentFactoryResolver,OnInit}来自'@angular/core';
从“./hello.component”导入{HelloComponent}
@组成部分({
选择器:“我的应用程序”,
templateUrl:“./app.component.html”,
样式URL:['./app.component.css']
})
导出类AppComponent实现OnInit{
@ViewChild('container',{read:ViewContainerRef,static:true})container:ViewContainerRef;
构造函数(专用componentFactoryResolver:componentFactoryResolver){
}
恩戈尼尼特(){
//动态实例化HelloComponent
const componentFactory=此.componentFactoryResolver.resolveComponentFactory(HelloComponent)
const componentRef=this.container.createComponent(componentFactory);
componentRef.instance.name='动态组件'
}
}
生成的DOM看起来正常,但由于某些原因,文本在页面上不可见:
您好,动态组件
请参见我想这里有两个问题:
svg
而不是g
对元素进行分组。在您的具体示例中,这意味着更改选择器:
@组件({
选择器:“svg[hello]”,
模板:`Hello,{{name}}`,
样式:[`h1{font-family:Lato;}`]
})
和app.component.html
:
您的选择器不包含
svg
命名空间。为了正确呈现,选择器应该是svg:g[hello]
但这是不可能的,因为自5年以来就存在一个老问题。
更多细节和细节 正如注释中提到的,这里的主要问题是角度选择器不能包含用于创建元素的名称空间。
选择器
svg:g[hello]
将被解析为g[hello]
,因此Angular将使用document.createElement
而不是document.createElements
来创建新元素
为什么使用svg[hello]
有效?因为如果我们使用选择器
svg[hello]
,那么它将被解析为
,对于这个标记:
'svg':新的HtmlTagDefinition({implicitNamespacePrefix:'svg'}),
似乎与未决问题有关,请参阅
似乎与旧的角度问题有关:,也与维塔利提到的问题有关: 在中,建议进行以下工作: 而不是此代码:
const componentRef=this.container.createComponent(componentFactory);
要使用此选项:
constgroupelement=document.createElements(“http://www.w3.org/2000/svg“,“g”);
const componentRef=componentFactory.create(injector,[],groupElement);
this.container.insert(componentRef.hostView)
此更改解决了问题,而无需将
替换为
。当然,一个公认的答案也解决了问题,但我对性能惩罚有一些担心,这可能会导致此类更换
工作stackblitz感谢您指出此问题。我最近还发现了另一个问题,这似乎也有关联:我在github问题上留下了一张便条。