渲染没有主机元素容器的嵌套组件 - 将 SVG 部分分成不同的组件



我有一个带有 SVG 元素的组件,我正在尝试将该 SVG 的各个部分分成不同的组件。 嵌套组件需要从父组件动态创建,这是因为我正在从 json 文件构建整个 SVG 图形,该文件确定需要添加哪些嵌套组件(SVG 嵌套形状(。

要动态创建组件,我正在使用ComponentFactoryResolver和ViewContainerRef。 从@angular/核心

@Component({
selector: 'skick-player',
templateUrl: './player.component.html',
styleUrls: ['./player.component.scss'],
})
export class PlayerComponent implements OnInit, AfterViewInit {
@ViewChild('svgContainer', { read: ViewContainerRef }) container;
constructor( private resolver: ComponentFactoryResolver) {}
performFrame() {
....
//Add nested component
const factory = this.resolver.resolveComponentFactory(
BackDropItemComponent
);
const componentRef = this.container.createComponent(factory);
componentRef.instance.imagePath = objectUrl;
}
}
});

}

问题是角度将嵌套组件包装在div 中:

<div _nghost-qon-c42="" skick-back-drop-item="" class="ng-star-inserted">

因此,由于创建了特殊元素标记,因此不会呈现它。如果删除该div 元素,它将正确呈现嵌套的 SVG。

我知道我可以将嵌套组件呈现为指令,它会工作,如下所示:

<svg>
<svg:g skick-back-drop-item />
</svg>

但是在我的用例中,控制器需要从父组件动态渲染,因此这种方法对我不起作用。

也许有没有办法按语法方式将(添加嵌套控制器(呈现为父组件的指令(请记住,嵌套组件具有@input属性(?

是否有可能拥有不可见的组件容器?在没有任何容器的情况下呈现嵌套组件的内容?


父模板:

<div class="patch-overlay" cdkDrag>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:svgjs="http://svgjs.dev/svgjs" width="100%" height="100%">
<<ng-container #svgContainer></ng-container>>
</svg>
</div>

嵌套组件模板(示例(:

<svg width="400" height="110">
<rect [attr.width]="width" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
</svg>

由于这在谷歌的第一页上显示为该问题的最新内容,因此似乎在所有情况下都有效的解决方法:使用显示内容。

@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.sass'],
host: {
style: "display: contents"
}
})
export class MyComponent {}

这是通过告诉浏览器表现得好像主机元素根本不存在一样工作;如果你确实检查元素,它仍然是html的一部分,但它不会成为任何渲染/大小/位置考虑的一部分。 附言:这确实比完全不包含在 html 中有一个优势,它仍然是 CSS 的可选 html 元素

我试着做你正在做的事情。我的错误包括构建专门的 FormGroup 组件(不要这样做(。最近,我使用 ControlValueAccessor 构建了一个组件,它运行良好,可以达到我的目的。

我没有使用ng-template及其相关功能构建任何内容,例如ngTemplateOutlet.但是,我怀疑这可能会对您有所帮助。ng-template在DOM中被移开,这就是你正在寻找的。

这是Angular Uniiveristy的解释。我还发现巴塞尔Netanel有很棒的信息。

如果你想尝试CVA路线,上周我刚刚完成了一个项目的重新编码,并在这里做了一堆关于SO的研究。找到一个涉及我想做什么的问题,然后回去写了一个对我有用的新答案。看看它,它可能会给你你需要的东西。

基于TurtleKwitty的出色答案,他们的确切解决方案给了我错误使用@HostBinding或@HostListener而不是host元数据属性

我通过将它移动到组件的.scss文件中来解决,如下所示:

:host {
display: contents;
}

希望对别人有帮助!

最新更新