我想操纵Angular2项目中的<SVG>
元素。我想在运行时在主<SVG>
标记内创建各种svg元素。我已经在angular.io(https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html)上阅读了有关动态组件创建的教程,我基本上都在使用它。但似乎Angular将每个组件包装在它自己的DOM元素中,以组件的选择器命名,或者在选择器后面命名的类/ id的简单DIV。因此,当我插入一个元素时,我得到的输出如下所示:
<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>
我想要的是以下内容:
<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>
但是我不能简单地对父SVG组件中的<circle>
进行硬编码,因为我需要创建和操作多种类型的内部组件。这在Angular2中是否可行?
这是我的代码。如果我遗漏了一些东西,请告诉我,我会添加它。
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;
}
}
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');
}
}
export interface SvgChildComponent {
// common interface to standardize the api for passing data to the SVG components
data: any;
}
import {Type} from '@angular/core';
export class SvgChildItem {
constructor(public component: Type<any>, public data: any) {}
}
import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[svg-child-host]',
})
export class SvgChildDirective {
constructor(public viewContainerRef: ViewContainerRef) { }
}