Svg 删除由angular component创建的宿主HTML元素选择器
在angular 2中,svg rect是一个创建rect的组件,如下所示Svg 删除由angular component创建的宿主HTML元素选择器,svg,angular,Svg,Angular,在angular 2中,svg rect是一个创建rect的组件,如下所示 <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="re
<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>
但由于创建了特殊的元素标记,因此这不会渲染rect。如果删除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:'true',它删除了带有编译输出的指令标记。我们能否在angular2中实现同样的功能?引用以下内容:
Angular 2中不支持替换其宿主元素的指令(Angular 1中的replace:true指令)。在许多情况下,这些指令可以升级为常规组件指令
在某些情况下,常规组件指令不起作用,在这些情况下,可以使用替代方法。有关svg的示例,请参见:
另一种删除我使用的组件主机的方法 指令
删除主机
//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);
}
}
使用本指令
根据使用案例,可能会有一些性能问题。不要试图删除宿主元素,而是将其转换为有效的SVG,但从其他方面看不会影响:而不是您的元素选择器
selector: "svg-rect"
以及模板中相应的元素:
template: `...<svg-rect>...</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,它将呈现。
还有另一种方法,我们可以从组件中获取组件的模板。
首先,我们创建组件,我们希望从浏览器渲染中删除该组件的标记(此处我们不尝试删除标记)
@组件({
选择器:“tl无标记”,
模板:`
{{value}}
`,
样式URL:[]
})
导出类TlNoTagComponent{
@ViewChild(“tmp”)tmp:任何;
数值=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>
五,
因此,我们从TlNoTagComponent中引入了{{value}}
<代码>
将继续存在,但不会阻止任何css或svg内容。类似于:
:host { display: contents; }
将其放入主机组件的css(或scss)文件将导致组件的框无法呈现
注:这对我来说很有效,但显然我会担心浏览器的兼容性,特别是如果你开发的是支持旧浏览器的话。我也很确定这还没有完全脱离“实验”阶段。文档中还指出,这可能会导致可访问性问题。可能是性能问题。这是我最初的想法。但目前在我的材质设计中使用这种方式,灯光组件将替换主体元素,否则会出现显示问题html@Kuncevich很高兴知道我的回答有帮助,当元素
ChangeDetection
被触发为shadowdom!==实际DOM
。但是,如果没有太多的元素,那么这将不会有那么大。希望如此;)我们需要一些Angular1的类比replace:true
有人说这个功能实际上是在angular2中,但没有得到官方的支持。@Kuncevic,情况正好相反。它仍然在Angular1,但在那里被弃用。这就是为什么他们首先不想在Angular2中添加它。事实证明,这导致了许多值得努力的问题。如果您考虑将此技术与正在更改数据的ngFor
一起使用,您会惊讶于UI无法正确更新。这在需要有效元素的任何地方都能很好地工作,我刚刚将其用于表头的一个小组件,其中出现了相同的问题。不过,有一个问题是,您可以为此链接到任何文档吗?@David-您在手册中找不到它(但要确保它是幸运的):下面是一个线程,用户认为有时(svg和表)需要使用属性选择器来修改结构:。作为回应,在此处添加了功能(实际上是恢复的):。但是如果我想在一个元素中添加多个元素(手动,而不是通过*ngFor),该如何向属性选择器添加属性?“模板是否有自己单独的变量范围,模板可以看到哪些变量?”请查看此项(在模板内容部分中):如果您打算使用*ngFor
来处理此数据,这是一种方法。我的方案是将
分组在一起。此代码非常有效。请确保在tl no标记上设置display:none
,这样它就不会干扰您的colspan
。这样一个简短、简单且有效的回答效果很好没有额外的解决方法。希望Angular会添加在某个点上不渲染宿主元素的选项。这对我不起作用。可能他们在Angular的一个较新版本中删除了此功能。如果有选择器需要直接后代,则这不一定起作用。非常感谢您的指示。我确信remo在AngularJS时代,我们可以使用AngularJS,但它显然是我们使用的元素:
<tl-no-tag></tl-no-tag>
<p>5</p>
:host { display: contents; }