Как закрыть раздел при щелчке снаружи, который идет из цикла и переключается в угловой 10

#javascript #angular

Вопрос:

У меня есть несколько изображений и информационный текст, поэтому, когда я нажимаю на изображение, для переключения/отображения используется определенный информационный текст. Кроме того, если открыть предыдущий информационный текст, он скроется, а следующий информационный текст появится при нажатии на любое другое изображение. Теперь мое требование-закрыть информационный текст снаружи, если он открыт. Вот код ниже. https://stackblitz.com/edit/angular-mb2rmb?file=src/app/app.component.html

app.component.html

 <hello name="{{ name }}"></hello>
<h3>How to show info of clicked image only</h3>

<div *ngFor="let x of things; let i = index">
  <img
    src="https://source.unsplash.com/200x200"
    alt="loading"
    (click)="clicked(i)"
  />

  <div *ngIf="x.show">
    <div class="names">
      <div class="fullName">{{ x.data }}</div>
      <div>{{ x.data2 }}</div>
    </div>
  </div>
</div>
 

приложение.компонент.ts

 import { Component,Renderer2,ElementRef,ViewChild } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  name = 'Angular';
  previousIndex: number = -1;
  public show: boolean = false;
  @ViewChild('toggleButton') toggleButton: ElementRef;
  @ViewChild('menu') menu: ElementRef;
  
  
  clicked(index) {
    // Checking if same picture clicked or new
    if (this.previousIndex >= 0 amp;amp; this.previousIndex != index) {
      //  If new picture is clicked then closing previous picture
      this.things[this.previousIndex].show = false;
    }
    // Updating index
    this.previousIndex = index;
    this.things[index].show = !this.things[index].show;
  }

  public things: Array<any> = [
    {
      data: 'information for img1:',
      data2: 'only the info img1 is displayed',
      show: false,
    },
    {
      data: 'information for img2:',
      data2: 'only the info for img2 is displayed',
      show: false,
    },
    {
      data: 'information for img3:',
      data2: 'only the  info for img3 is displayed',
      show: false,
    },
  ];
}
 

Комментарии:

1. ng-click-outside работает довольно хорошо. Вам просто нужно html, body { min-height: 100%; } , чтобы он работал везде.

Ответ №1:

СПОСОБ 1
Измените clicked функцию, чтобы событие было параметром

 (click)="clicked(i, $event)"
 

amp;

 clicked(index, event) {
    // Checking if same picture clicked or new
    if (this.previousIndex >= 0 amp;amp; this.previousIndex != index) {
      //  If new picture is clicked then closing previous picture
      this.things[this.previousIndex].show = false;
    }
    // Updating index
    this.previousIndex = index;
    this.things[index].show = !this.things[index].show;
    event.stopPropagation();
}
 

Добавьте еще одну функцию для хоста:

   hostClick(e) {
    this.things.forEach((element)=>{
      element.show = false;
    });
  }
 

и обновите component метаданные с помощью события щелчка по хосту

 @Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  host: {
    "(click)": "hostClick($event)"
  }
})
 

Для справки, Рабочий пример для метода 1

В принципе, event.stopPropagation(); предотвращает дальнейшее распространение текущего события для размещения событий щелчка. Событие щелчка хоста запускается в любом месте внутри хоста ( компонента ).

СПОСОБ 2
Импортируйте список узлов в компонент

 import { Component,Renderer2,ElementRef,ViewChild, HostListener } from '@angular/core';
 

и используйте HostListener для привязки функции

 @HostListener("click", ["$event"])
   hostClick(event: any): void {
    this.things.forEach((element)=>{
          element.show = false;
        });
   }
 

обновите выбранную функцию так же, как в методе 1

 (click)="clicked(i, $event)"
 

amp;

 clicked(index, event) {console.log(index);
    // Checking if same picture clicked or new
    if (this.previousIndex >= 0 amp;amp; this.previousIndex != index) {
      //  If new picture is clicked then closing previous picture
      this.things[this.previousIndex].show = false;
    }
    // Updating index
    this.previousIndex = index;
    this.things[index].show = !this.things[index].show;
    event.stopPropagation();
  }
 

Для справки, Рабочий пример для метода 2