如何防止Angular2在DOM元素中包装组件?

时间:2017-01-31 21:31:46

标签: angular angular2-template angular2-directives

我想操纵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中是否可行?

这是我的代码。如果我遗漏了一些东西,请告诉我,我会添加它。

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) { }
}

0 个答案:

没有答案