es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Alternar variable booleana de componentes hermanos ubicados dentro de un ngFor en Angular.

El caso es el siguiente, un ngFor renderiza una colección de componentes (app-item). Cada componente tiene una variable booleana llamada “open” y una función llamada “toggle” que cambia (verdadero o falso) el estado de la variable.

¿Cómo puedo hacer clic en el botón de un componente (app-item) y cambiar el estado de los otros elementos hermanos iterados?

app-page.component.html

<div *ngfor="let item of items">
  <app-item [data]="item"></app-item>
</div>

app-item.component.html

<button (click)="toggle($event)">Cambiar variable "open"</button>
<div *ngif="open">El contenido es ahora visible</div>

app-item.component.ts

export class ItemComponent {
  open: boolean = false;

  toggle(event: any) {
    this.open = !this.open;
  }
}
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para cambiar el estado de los elementos hermanos iterados restantes al hacer clic en el botón de un componente, podemos implementar la siguiente solución:

    1. Inyectar los servicios Renderer2 y ElementRef en el archivo app-page.component.ts:
    import { Component, Renderer2, ElementRef } from '@angular/core';
    
    @Component({
      selector: 'app-page',
      templateUrl: './app-page.component.html',
      styleUrls: ['./app-page.component.css']
    })
    export class AppPageComponent {
      items: any[] = [
        { id: 1, name: 'Item 1' },
        { id: 2, name: 'Item 2' },
        { id: 3, name: 'Item 3' },
        { id: 4, name: 'Item 4' },
        { id: 5, name: 'Item 5' }
      ];
    
      constructor(private renderer: Renderer2, private el: ElementRef) {}
    
      toggleSiblings(item: any) {
        const siblings = this.el.nativeElement.querySelectorAll('.item-class');
        siblings.forEach((sibling: any) => {
          const siblingComponent = sibling.__ngContext__[8]; // El índice puede variar según el contexto de su componente
          if (siblingComponent.item.id !== item.id) {
            siblingComponent.toggle();
          }
        });
      }
    }
    
    1. Modificar el archivo app-item.component.html para pasar el objeto item al método toggle:
    <button (click)="toggle(item)">Alternar variable "open".</button>
    <div *ngif="open" class="item-class">El contenido es visible ahora</div>
    
    1. Añadir el método toggleSiblings al archivo app-item.component.ts y llamarlo desde el método toggle:
    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-item',
      templateUrl: './app-item.component.html',
      styleUrls: ['./app-item.component.css']
    })
    export class AppItemComponent {
      data: any;
      open: boolean = false;
    
      constructor() {}
    
      toggle(item: any) {
        this.open = !this.open;
        const parent = document.querySelector('.container-class'); // Cambie el selector para que coincida con su elemento padre
        parent.__ngContext__[8].toggleSiblings(item); // El índice puede variar según el contexto de su componente
      }
    
      toggleSiblings(item: any) {}
    }
    
    1. Añadir la clase .container-class al elemento padre del bucle ngFor en el archivo app-page.component.html:
    <div class="container-class">
      <div *ngfor="let item of items">
        <app-item [data]="item"></app-item>
      </div>
    </div>
    

    Ahora, al hacer clic en el botón de un componente, se llamará al método toggle y alternará la variable open del elemento actual. Luego, llamará al método toggleSiblings pasando el elemento actual como parámetro, el cual iterará sobre todos los elementos hermanos y alternará su variable open excepto el elemento actual.

Comments are closed.