删除由angular度组件创build的主机HTML元素select器

在angular2中, svg-rect是一个像下面那样创build矩形的组件,

<svg height="550" width="450" x="0" y="0"> <g id="svgGroup"> <svg-rect> <!--template bindings={}--> <rect x="10" y="10" height="100" width="100" fill="red" stroke="#000" stroke-width="2"></rect> <!--template bindings={}--> </svg-rect> <svg-rect> <!--template bindings={}--> <rect x="10" y="10" height="100" width="100" fill="red" stroke="#000" stroke-width="2"></rect> <!--template bindings={}--> </svg-rect> </g> </svg> 

但是由于创build了特殊的元素标签,这将不会渲染。 如果svg-rect标签被删除,则呈现rect

 <svg height="550" width="450" x="0" y="0"> <g id="svgGroup"> <!--template bindings={}--> <rect x="10" y="10" height="100" width="100" fill="red" stroke="#000" stroke-width="2"></rect> <!--template bindings={}--> <!--template bindings={}--> <rect x="10" y="10" height="100" width="100" fill="red" stroke="#000" stroke-width="2"></rect> <!--template bindings={}--> </g> </svg> 

在Angular 1.x中,有replace:“真” ,它删除与编译输出的指令标签。 我们可以在angular2中实现吗?

而不是试图摆脱主机元素,把它变成一个有效的SVG,但其他明智的不受影响:而不是你的元素select器

 selector: "svg-rect" 

及其在模板中的相应元素:

 template: `...<svg-rect>...</svg-rect>...` 

切换到一个属性select器

 selector: "[svg-rect]" 

并将该属性添加到组元素标记中:

 template: `...<g svg-rect>...</g>...` 

这将扩展到:

 <svg height="550" width="450" x="0" y="0"> <g id="svgGroup"> <g svg-rect> <!--template bindings={}--> <rect x="10" y="10" height="100" width="100" fill="red" stroke="#000" stroke-width="2"></rect> <!--template bindings={}--> </g> <g svg-rect> <!--template bindings={}--> <rect x="10" y="10" height="100" width="100" fill="red" stroke="#000" stroke-width="2"></rect> <!--template bindings={}--> </g> </g> </svg> 

这是有效的SVG,它将呈现。 Plnkr

另一种方法来删除我使用的组件的主机。

指令remove-host

 //remove the host of avatar to be rendered as svg @Directive({ selector: '[remove-host]' }) class RemoveHost { constructor(private el: ElementRef) { } //wait for the component to render completely ngOnInit() { var nativeElement: HTMLElement = this.el.nativeElement, parentElement: HTMLElement = nativeElement.parentElement; // move all children out of the element while (nativeElement.firstChild) { parentElement.insertBefore(nativeElement.firstChild, nativeElement); } // remove the empty element(the host) parentElement.removeChild(nativeElement); } } 

使用这个指令;
<avatar [name]="hero.name" remove-host></avatar>

remove-host指令中, nativeElement所有子nativeElement都被插入主机之前,然后主机元素被删除。

示例示例
根据用例,可能会有一些性能问题。

引用Angular 1到Angular 2升级策略doc :

Angular 2中不支持replace其主机元素的指令(取代:Angular 1中的true指令)。在很多情况下,这些指令可以升级到常规的组件指令。

有些情况下,常规组件指令不起作用,在这种情况下,可以使用替代方法。 例如svg请参阅: https : //github.com/mhevery/ng2-svg

还有另一种方法可以从组件中获取组件的模板。
首先,我们创build一个组件,我们希望它的标签可以从浏览器中移除(我们并不试图在这里删除标签)。

 @Component({ selector: 'tl-no-tag', template: ` <template #tmp> <p>{{value}}</p> </template>`, styleUrls: [] }) export class TlNoTagComponent { @ViewChild('tmp') tmp: any; value = 5; } 

然后,在另一个组件的模板中,我们写:

 <tl-no-tag #source></tl-no-tag> <!-- This line can be placed anywhere --> <template [ngTemplateOutlet]="source.tmp"></template> <!-- This line will be placed where needed --> 

然后,我们在浏览器中这样的东西:

 <tl-no-tag></tl-no-tag> <p>5</p> 

所以,我们已经将<p>{{value}}</p>从TlNoTagComponent中移出。 <tl-no-tag></tl-no-tag>将继续存在,但不会阻止任何css或svg事物。