I would like to manipulate an <SVG> element within an Angular2 project. I 
would like to create various svg elements within the main <SVG> tag at 
runtime. I have read the tutorial on dynamic component creation on 
angular.io (
https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html), 
and I have it basically working. But it seems like Angular wraps each 
component in its own DOM element, named after either the component's 
selector, or a simple DIV with a class/id named after the selector. So when 
I insert an element, I get output that looks like the following:


<svg id="logo" style="border: 3px solid black" viewBox="0 0 600 400" 
width="600" height="400">
    <svgcirclecomponent>
        <circle r="100" cx="10" cy="10"></circle>
    </svgcirclecomponent>
</svg>


What I would LIKE to have is the following:


<svg id="logo" style="border: 3px solid black" viewBox="0 0 600 400" 
width="600" height="400">
    <circle r="100" cx="10" cy="10"></circle>
</svg>


However I cannot simply hard-code the <circle> in the parent SVG component, 
since I need to create and manipulate multiple types of inner components. 
Is this possible in Angular2?

Here is my code. If I've left something out let me know and I'll add it.

svg.component.ts

import { Component, Input, Output, ViewEncapsulation, ViewChild, 
ComponentFactoryResolver } from '@angular/core';
import {MdButton} from '@angular/material';
import {SvgChildItem} from './svgChildComponents/svgChildItem';
import {SvgChildDirective} from './svgChildComponents/svgChild.directive';
import {SvgChildComponent} from './svgChildComponents/svgChild.component';
import {SvgCircleComponent} from './svgChildComponents/svgCircle.component';

@Component({
  selector: 'svgCanvasComponent',
  template: `
    <button md-button (click)="addNewComponent()">Add Circly</button><br />
    <svg width="800" height="800" viewBox="0 0 800 800">
        <template svg-child-host></template>
    </svg>
  `
})
export class SvgCanvasComponent  {
    @ViewChild(SvgChildDirective) svgChildHost: SvgChildDirective;

    constructor(private _componentFactoryResolver: ComponentFactoryResolver) {}

    addNewComponent() {
        console.log('adding circly');
        let svgChildItem = new SvgChildItem(SvgCircleComponent, {"x":10, 
"y":20});
        let cmpFact = 
this._componentFactoryResolver.resolveComponentFactory(svgChildItem.component);
        let viewContainerRef = this.svgChildHost.viewContainerRef;
        let componentRef = viewContainerRef.createComponent(cmpFact);
        (<SvgChildComponent>componentRef.instance).data = svgChildItem.data;
    }
}


SvgCircle.component.ts

import {Component, Input, ViewEncapsulation} from '@angular/core';
import {NnpUtilModule} from '../../nnpUtil.module';

import {SvgChildComponent} from './svgChild.component';

@Component({
    selector: "svgCircleComponent"
    ,template: `
        <svg:circle [attr.cx]="x" [attr.cy]="y" r="100">
    `
    ,encapsulation: ViewEncapsulation.None
})
export class SvgCircleComponent implements SvgChildComponent {
    @Input() x: number;
    @Input() y: number;

    @Input() data: any;  //  from SvgChildComponent interface

    constructor() {
        //[this.x, this.y] = [Math.random(), Math.random()];
        [this.x, this.y] = [10, 10];
        //console.log(NnpUtilModule.getFive());  //  TODO: load this from a 
service so everyone can share the util?
        console.log('constructing SvgCircleComponent');
    }
}


SvgChild.component.ts

export interface SvgChildComponent {
    //  common interface to standardize the api for passing data to the SVG 
components
    data: any;
}


SvgChildItem.ts

import {Type} from '@angular/core';

export class SvgChildItem {
    constructor(public component: Type<any>, public data: any) {}
}


svgChild.directive.ts

import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[svg-child-host]',
})
export class SvgChildDirective {
  constructor(public viewContainerRef: ViewContainerRef) { }
}

-- 
You received this message because you are subscribed to the Google Groups 
"Angular and AngularJS discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Reply via email to