How to create an SVG component dynamically in Angular2?

后端 未结 3 924
灰色年华
灰色年华 2021-01-06 10:09

I am creating a web application which uses SVG. I have created components consist of SVG element, and they are put into a root svg element. They have attribute

相关标签:
3条回答
  • 2021-01-06 10:46

    You're right about the namespacing issues keeping the g element from rendering as svg. Unfortunately, attaching the node as an svg element is the only way to feasibly get the component to namespace properly.

    However, this doesn't mean this won't work. If you add the drag functionality as a directive on the g element in the template, it will be compiled with your component, and you can offset your logic into that directive. The top level svg will be namespaced correctly, and the template will inherit this accordingly.

    import {Component, Input} from '@angular/core';
    
    @Component({
      selector: 'svg:svg[customName]', // prevent this from hijacking other svg
      template: '<svg:g dragDirective>...</svg:g>', // note the directive added here
      style: []
    })
    export class GComponent {
    
      constructor() { }
    
    }
    

    This may not be ideal, but until https://github.com/angular/angular/issues/10404 is resolved, there's not much of an alternative.

    0 讨论(0)
  • 2021-01-06 10:52

    I am not sure that my solution is right but it works for me (even with ivy):

    @Component({
    ...
    })
    class ParentComponent {
        constructor(
            private injector: Injector,
            private appRef: ApplicationRef,
            private componentFactoryResolver: ComponentFactoryResolver,
        ) {}
    
        createDynamicComponent() {
            let node = document.createElementNS("http://www.w3.org/2000/svg", "svg");
            let factory = this.componentFactoryResolver.resolveComponentFactory(DynamicComponent);
            let componentRef = factory.create(this.injector, [], node);
    
            this.appRef.attachView(componentRef.hostView);
        }
    }
    

    After that you must manually append node into DOM.

    0 讨论(0)
  • 2021-01-06 11:04

    Instead of trying to create your component to the view with the Component Resolver I will do this instead.

    • Create a object with properties which match the attributes you want to pass to your SVG Component.
    • Append this object to an array (ex.svgItems).
    • Add *ngFor="svgItem in svgItems" to the SVG component you want to create dynamically.

    Hope it's clear and solve your problem.

    0 讨论(0)
提交回复
热议问题