首页 > 解决方案 > 在没有宿主元素容器的情况下渲染嵌套组件 - 将 SVG 部分分成不同的组件

问题描述

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

为了动态创建组件,我使用了 ComponentFactoryResolver 和 @angular/core 的 ViewContainerRef

@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;
    }
  }
});

}

问题是 angular 将嵌套组件包装在 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>

标签: angularsvgangular-directiveangular-components

解决方案


我试着做你正在做的事情。我的错误包括构建专门的 FormGroup 组件(不要那样做)。最近,我使用ControlValueAccessor构建了一个组件,它工作得非常好并且符合我的目的。

我没有用ng-template它及其相关的特性构建任何东西,比如ngTemplateOutlet. 但是,我怀疑这可能会对您有所帮助。ng-template在 DOM 中被移开,这正是您要寻找的。

这是 Angular 大学的解释。我还发现 Netanel Basel 有很好的信息

如果你想尝试 CVA 路线,上周我刚刚完成了一个项目的重新编码,并在这里对 SO 进行了大量研究。发现了一个涉及我想做的事情的问题,然后回去写了一个对我有用的新答案。看看吧,它可能会给你你需要的东西。


推荐阅读