Búsqueda de sitios web

javascript - El elemento de Angular se destruye en mat-tab-group cuando se agrega una nueva pestaña


Tengo un mat-tab-group que se llena a partir de un arreglo. Agrego nuevos elementos al arreglo dinámicamente y el contenido de las pestañas son componentes de Angular Elements.

Cuando agrego un nuevo elemento, todo funciona bien y veo el nuevo elemento agregado, pero cuando agrego un nuevo elemento, el elemento anterior se destruye y el contenido de la pestaña aparece vacío.

He inspeccionado un elemento cuando se agrega y veo que funciona perfectamente, pero cuando agrego un nuevo elemento, puedo ver que el anterior desaparece del DOM.

He intentado añadir texto normal en las pestañas en lugar de componentes de Angular Elements y todo funciona como se espera y puedo moverme hacia atrás y adelante en las pestañas.

El grupo de pestañas HTML es este:

<mat-tab-group [selectedIndex]="selectedTab">
  <mat-tab *ngFor="let tab of tabs; let i = index" [label]="tab.name">
    <div [innerHTML]="tab.content"></div>
  </mat-tab>
</mat-tab-group>

El código que agrega una nueva pestaña es este:

this.tabs.push({
  name: this.options[opt].name,
  content: this.domSanitizer.bypassSecurityTrustHtml('<osm-'+this.options[opt].content+'></osm-'+this.options[opt].content+'>')
} as MainTab);
this.selectedTab = this.tabs.length -1;

La matriz options es una lista de las posibles nuevas pestañas que se pueden agregar:

options = [
  {id: 1, name: 'Sell', content: 'sell'},
  {id: 2, name: 'Admin', content: 'admin'}
];

Y los componentes osm-sell y osm-admin se han creado como componentes de Angular Elements (como se describe en esta guía.

Todo el código está en Github.

El resultado esperado debería ser lo que ocurre en el primer paso, se agrega una nueva pestaña con el componente en su contenido, pero se destruye al agregar una nueva.

Una prueba en vivo está en https://tpv.osumi.es

¡Gracias!!

Respuesta #1

Porque al hacer push a un arreglo se dispara una detección de cambios, y tus pestañas no se rastrean correctamente, por lo que el framework las vuelve a renderizar.

Intenta usar una pista personalizada por función:

*ngFor="let tab of tabs; let i = index; trackBy: customTB"

En tu TS

customTB(index, tab) {
  return tab.id;
}