#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