Eliminar los selectores de elemento HTML del host creados por el componente angular


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 renderizará rect debido a las etiquetas de elemento especiales creadas. Si se eliminan las etiquetas svg-rect , renderiza 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 reemplazar: 'verdadero' que elimina las etiquetas de directiva con la salida compilada. ¿Podemos implementar lo mismo en angular2?

 33
Author: peterh, 2015-12-15

5 answers

En lugar de intentar deshacerse del elemento host, conviértalo en uno que sea SVG válido pero que 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 añadir 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>

Que es SVG válido, que se renderizará. Plnkr

 23
Author: John C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-08 19:33:54

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

Utilizando la presente directiva;
<avatar [name]="hero.name" remove-host></avatar>

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

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

 25
Author: Bhavik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-07 06:04:48

Hay otro enfoque que podemos obtener 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>

Así que hemos sacado <p>{{value}}</p> del componente Tlnotag. <tl-no-tag></tl-no-tag> seguirá allí, pero no bloqueará ningún css o svg-cosa.

 6
Author: Timathon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-30 08:37:46

Para citar la estrategia de actualización de Angular 1 a Angular 2 doc :

Las directivas que reemplazan su elemento host (replace: true directives 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 los que las directivas de componentes regulares no van a funcionar, en esos casos se pueden usar enfoques alternativos. Por ejemplo para svg ver: https://github.com/mhevery/ng2-svg

 4
Author: Mark Rajcok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-15 03:25:32

¿Qué pasa con algo como:

:host { display: contents; }

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

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

 1
Author: tlm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-12 09:55:03