En Angular, un componente es una directiva especial, y su característica especial es que tiene su propia plantilla (html) y estilo (css). Por lo tanto, usar componentes puede hacer que nuestro código sea altamente desacoplado, reutilizable y fácilmente extensible. Los componentes habituales se definen de la siguiente manera:
demo.component.ts:
demo.component.html:
demo.component.scss:
Cuando hacemos referencia al componente, el contenido analizado del componente se representa:
Supongamos que el componente necesita aceptar contenido proyectado externamente, lo que significa que el componente acaba presentando más que solo lo que define. En este momento, se invita al protagonista de este artículoNG-contenido。
Proyección simple
Empecemos por lo más sencillo: añadir el demo.component.html modificado y demo.component.scss a demo.component.html, de la siguiente manera:
demo.component.html:
demo.component.scss:
Para efectos de efecto, el color de fondo del recipiente se define deliberadamente como naranja.
En este punto podemos transmitir contenido desde fuera al referenciar el componente, y el contenido externo se mostrará en el área naranja:
Proyección dirigida
Si hay varios a la vez, ¿cómo se proyectará el contenido externo?
Veamos un ejemplo primero: para distinguir, añadí un área azul, el demo.component.html modificado y demo.component.scss de la siguiente manera:
demo.component.html:
demo.component.scss:
Para referenciar el componente:
En este punto, veremos que el contenido externo se proyecta en el área azul:
Por supuesto, si pones el prefijo naranja después del prefijo azul, entonces el contenido externo se proyectará en el área naranja:
Así que, a partir del ejemplo anterior, podemos ver que si también existe un simple , entonces el contenido externo se proyectará en el último de la plantilla de componentes.
Así que, conociendo este problema, podríamos preguntarnos, ¿podemos proyectar contenido externo de forma específica? La respuesta es obviamente sí.
Para lidiar con esto, apoya a unoescogerAtributos que te permiten proyectar contenido específico en un lugar concreto. Esta propiedad soporta selectores CSS (selector de etiquetas, selector de clases, selector de atributos、... ) para que coincida con lo que quieres. Si no se asigna ningún atributo select en ng-content, recibirá el contenido completo o el contenido que no coincida con ningún otro elemento de ng-content.
Mirando directamente el ejemplo, el demo.component.html modificado y demo.component.scss son los siguientes:
demo.component.html:
demo.component.scss:
Como puedes ver en el código anterior, el área azul recibirá la parte del encabezado de etiqueta, el área roja recibirá la parte del div con la clase "demo2", el área verde recibirá la parte del div con el nombre de propiedad "demo3" y el área naranja recibirá el resto del contenido externo (inicio, I soy el contenido del embeding externo, fin).
Para referenciar el componente:
En este punto, veremos el contenido externo proyectado en el archivo especificado .
Ampliar el conocimiento
ngProjectAs
Ahora sabemos que la propiedad select de ng-content permite especificar que el contenido externo se proyecta en un dado .
Para proyectar correctamente el contenido basándose en el atributo select, existe una limitación: ya sea un encabezado de etiqueta, un div con clase "demo2" o un div con un nombre de propiedad "demo3", todas estas etiquetas son subnodos directos de la etiqueta componente.
¿Qué pasaría si no fuera por ser un subnodo directo? Simplemente modifiquemos el código que hace referencia al componente demo-component, pongamos el encabezado de etiqueta en un div y lo modifiquemos de la siguiente manera:
En este punto, vemos que la parte de cabecera de pestaña del contenido ya no se proyecta en el área azul, sino en el área naranja. La razón es que <ng-content select="encabezado"></ng-content> no puede coincidir con el encabezado anterior de la etiqueta, por lo que esta parte del contenido se proyecta en el <ng-content></ng-content> área naranja.
Para resolver este problema, tenemos que usar la propiedad ngProjectAs, que puede aplicarse a cualquier elemento. Los detalles son los siguientes:
Al establecer la propiedad ngProjectAs, el div donde está ubicado el encabezado de etiqueta apunta a select="encabezado", y la parte del encabezado se proyecta al área azul:
<ng-content>No "generes" contenido Haz un experimento Para hacer un experimento, primero define un componente demo-hijo-componente:
Componente demo-componente a:
Luego, en demo-component, cast demo-hijo-componente:
En este punto, en la consola vemos que la inicialización del componente demo-hijo está completa. Estas palabras. Pero cuando hacemos clic en el botón para cambiar de operaciones, ¡la inicialización del demo-hijo-componente está completa! Ya no se imprime, lo que significa que nuestro componente demo-hijo-componente solo se instancia una vez, nunca se destruye ni se recrea.
¿Por qué está pasando esto?
Causas de la ocurrencia
<ng-content> No "produce" contenido, solo proyecta contenido existente. Puedes pensar en ello como equivalente a node.appendChild(el) o al método $(node).append(el) en jQuery: con estos métodos, el nodo no se clona, simplemente se mueve a su nueva ubicación. Por lo tanto, el ciclo de vida del contenido proyectado estará limitado al lugar donde se declara, no se mostrará en su lugar.
Esto también explica la pregunta anterior del principio:Si hay varios a la vez, ¿cómo se proyectará el contenido externo?
Este comportamiento se realiza por dos razones: la consistencia y el rendimiento. ¿Qué significa "consistencia deseada" que, como desarrollador, puedes adivinar el comportamiento de tu aplicación basándote en su código. Supongamos que escribí el siguiente código:
Obviamente, el componente demo-hijo-componente se instanciará una vez, pero ahora si usamos un componente de una biblioteca de terceros:
Si una biblioteca de terceros tiene control sobre el ciclo de vida de un componente demo-hijo, no tendré forma de saber cuántas veces se ha instanciado. La única forma de hacerlo es mirar el código de las bibliotecas de terceros para entender su lógica interna de procesamiento. El significado de vincular el ciclo de vida de un componente a nuestros componentes de aplicación en lugar de wrappers es que los desarrolladores pueden controlar que los contadores se instancian solo una vez, sin conocer el código interno de las bibliotecas de terceros.
Razones de la interpretaciónes más importante. Como ng-content es solo un elemento móvil, puede hacerse en tiempo de compilación, no en tiempo de ejecución, lo que reduce considerablemente la carga de trabajo de la aplicación real.
Solución alternativa
Para que el componente controle la instanciación de los subcomponentes proyectados, podemos hacerlo de dos maneras: usando <ng-template> elementos y ngTemplateOutlets alrededor de nuestro contenido, o usando directivas de estructura con sintaxis "*". Para simplificar, usaremos Syntax en el ejemplo <ng-template> .
Componente demo-componente a:
Luego incluimos demo-hijo-componente en ng-plantilla:
En este punto, cuando pulsamos el botón para cambiar, la consola se imprimirá¡Inicialización del componente demo-hijo-de-forma completada!Estas palabras.
|