Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Html 角度:使用ComponentFactoryResolver动态实例化组件,在SVG内部呈现_Html_Angular_Svg - Fatal编程技术网

Html 角度:使用ComponentFactoryResolver动态实例化组件,在SVG内部呈现

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

我有一个呈现DOM的组件,它应该位于
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问题上留下了一张便条。