Transclusión angular de 2+ componentes frente a componentes padre-hijo

Acabo de aprender sobre la transclusión en Angular, pero no sé en qué escenario sería bueno usarlo o cuál es su propósito.

si hay alguna diferencia? o tal vez es una buena práctica utilizar uno de ellos? o ¿para qué usarías la transclusión?

Digamos que tengo este componente, ¿por qué transcluiría datos en él en lugar de simplemente escribirlo dentro? Escenario 1:

import { Component } from '@angular/core';

@Component({
  selector: 'my-component',
  template: `
    <div class="my-component">
      'My component works!'
    </div>
  `
})
export class MyComponent {}

escenario 2 (tranclusión):

import { Component } from '@angular/core';

@Component({
  selector: 'my-component',
  template: `
    <div class="my-component">
      <ng-content></ng-content>
    </div>
  `
})
export class MyComponent {}

y en el componente de la aplicación

<div class="app">
  <my-component>
    'My component works!'
  </my-component>
</div>

y seria algo similar con componentes child-parent

<div class="my-component">
  <child-component></child-component>
</div>

contra

Componente principal:

<div class="my-component">
  <ng-content></ng-content>
</div>

componente de la aplicación:

<div class="app">
  <my-component>
    <child-component></child-component>
  </my-component>
</div>
Answer

Esta es una buena pregunta y se hará evidente cuanto más tiempo pases con Angular. Recordando que existen componentes para compartimentar el comportamiento, vale la pena pensar qué comportamiento está compartimentando.

Digamos que desea ingresar nombres en su aplicación y siempre desea que los nombres aparezcan e interactúen de la misma manera con su usuario. En este caso, tiene sentido crear un componente de nombres que ingrese los nombres de la misma manera en todas partes, y el formulario que necesita el nombre nunca necesita preocuparse por cómo se procesan o recopilan los nombres. En este caso, tiene sentido una relación padre-hijo, donde el niño encapsula completamente su propio comportamiento (y todo el comportamiento del niño).

Por el contrario, supongamos que desea crear una tarjeta con contenido variable. Sabes que quieres que los bordes sean siempre los mismos, que el título tenga la misma fuente, que el relleno sea el mismo. Pero las cosas en el medio cambiarán, y en realidad no importa en relación con el estilo de la tarjeta. Esta es una oportunidad perfecta para la transclusión. Usted crea un componente que encapsula un cierto conjunto de estilo y comportamiento, mientras es independiente del contenido que se le pasa. Si desea ingresar una entrada en la tarjeta, el padre puede hacerlo y vincular esa entrada directamente en su propio formulario en lugar de crear un nuevo hijo solo para ese caso.

En resumen, la transclusión le brinda la oportunidad de reutilizar un componente de manera flexible manteniendo ciertos comportamientos y estilos consistentes en formas de bajo esfuerzo. Una relación padre-hijo tradicional sin transclusión le permite encapsular completamente un comportamiento específico (y determinista) para que el padre pueda usarlo ignorando por completo cualquiera de sus contenidos.

La transclusión permite que su componente no se preocupe por su contenido y, en cambio, permite que su componente se centre en su propósito. Por ejemplo, un componente de acordeón no necesita saber qué contendrá su cuerpo; puede ser solo texto simple, una tabla, un gráfico, una lista o una combinación de estos. Entonces, un componente de acordeón usaría la transclusión para permitir que su consumidor proporcione ese contenido.

La transclusión también permite la reutilización. Imagine crear una biblioteca de interfaz de usuario que contenga un botón, y el diseño del botón le permite al consumidor colocar contenido más complejo como una imagen y una etiqueta en todo tipo de formas. O una casilla de verificación que acepta una entrada de texto como etiqueta pero que también permite al consumidor proporcionar esa etiqueta como una imagen.

Sin embargo, los componentes que usan transclusión aún pueden identificar o interactuar con su contenido usando @ContentChild o @ContentChildren.