maticonregistry icon svg angular

svg - icon - Elimine los selectores de elementos HTML del host creados por componente angular



svg angular 4 (5)

En angular 2, svg-rect es un componente que crea rect como a continuación,

<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>

pero esto no se procesará correctamente debido a las etiquetas de elementos especiales creadas. Si se eliminan las etiquetas svg-rect , representa el 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>

En Angular 1.x, hay replace: ''true'' que elimina las etiquetas de directiva con la salida compilada. ¿Podemos implementar lo mismo en angular2?


¿Qué pasa con algo como:

:host { display: contents; }

Poner eso en el archivo css (o scss) del componente host hará que el cuadro del componente no se procese.

NB: Me ha funcionado antes, pero obviamente me preocuparía la compatibilidad del navegador, especialmente si está desarrollando para admitir navegadores más antiguos. También estoy bastante seguro de que eso no está completamente fuera de la fase "experimental". Los documentos también indican que esto puede causar problemas de accesibilidad.


En lugar de tratar de deshacerse del elemento host, conviértalo en uno que sea SVG válido pero que de otra manera no afecte: en lugar de su selector de elemento

selector: "svg-rect"

y su elemento correspondiente en la plantilla:

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

cambiar a un selector de atributos :

selector: "[svg-rect]"

y agregue ese atributo a una etiqueta de elemento de grupo:

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

Esto se expandirá a:

<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>

cuál es SVG válido, que rendirá. Plnkr


Hay otro enfoque en el que podemos sacar la plantilla de un componente del componente.
Primero, creamos el componente, cuya etiqueta esperamos eliminar del renderizado del navegador (no estamos tratando de eliminar la etiqueta aquí).

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

Luego, en la plantilla de otro componente, escribimos:

<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 -->

Entonces, tenemos en el navegador algo como esto:

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

Entonces, hemos sacado <p>{{value}}</p> del TlNoTagComponent. <tl-no-tag></tl-no-tag> continuará allí, pero no bloqueará ningún css o svg-thing.


Otro enfoque para eliminar el host del componente que uso.

Directiva 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); } }

Usando esta directiva;
<avatar [name]="hero.name" remove-host></avatar>

En la directiva remove-host , todos los elementos nativeElement de nativeElement se insertan antes del host y luego se elimina el elemento host.

Ejemplo de ejemplo Gist
Según el caso de uso, puede haber algunos problemas de rendimiento.


Para citar el documento de estrategia de actualización de Angular 1 a Angular 2 :

Las directivas que reemplazan su elemento host (replace: directivas verdaderas en Angular 1) no son compatibles con Angular 2. En muchos casos, estas directivas se pueden actualizar a directivas de componentes regulares.

Hay casos en que las directivas de componentes regulares no van a funcionar, en esos casos se pueden usar enfoques alternativos. Por ejemplo, para svg, consulte: https://github.com/mhevery/ng2-svg