html - Angular overlaypanel förblir alltid öppet
Jag har skapat en Angular-komponent som p-overlaypanel men den förblir öppen för varje objekt jag klickar på. Jag vill att om jag klickar på en annan overlay-panel ska den senaste klickade döljas. Jag vill att endast en ska klickas och visas, inte alla. Nedan kan du hitta kod i Stackblitz.
https://stackblitz.com/edit/angular-yrsyt6?file=src/app/app.component.ts
Här är koden
<div class="dropdown">
<div class="body">
<ng-content select="[body]"></ng-content>
</div>
<div *ngIf="active" class="popup">
<ng-content select="[popup]"></ng-content>
</div>
</div>
.dropdown {
position: relative;
display: inline-block;
}
.popup {
display: block;
position: absolute;
z-index: 1000;
}
export class OverlaypanelComponent implements OnInit {
active = false;
constructor() {
}
ngOnInit() {
}
@HostListener('document:click', ['$event']) clickedOutside($event) {
this.active = false;
}
toggle($event) {
$event.preventDefault();
$event.stopPropagation();
this.active = !this.active;
}
close() {
this.active = false;
}
}
Svar #1
För att göra detta måste du få barnkomponenten (panelen) att på något sätt meddela föräldern att den har öppnats, och det kommer att vara förälderns ansvar att stänga de andra panelerna. I det syftet bör active-egenskapen också vara en Input-bindning. Detta innebär tillsatsen av minst tre saker på ett eller annat sätt: en Input-bindning för att avgöra om panelen är aktiv, en Input-bindning för att identifiera panelen, och en Output-bindning för att signalera att panelen visas:
@Input() active = false;
@Output() activeChanged = new EventEmitter();
@Input() index;
toggle($event) {
$event.preventDefault();
$event.stopPropagation();
this.active = !this.active;
if (this.active) {
this.activeChanged.emit(this.index);
}
}
Nu kommer din överordnade komponent att behöva binda till dessa egenskaper och också svara på Output för att ändra bindningarna av de andra panelerna. Detta borde vara ganska lätt att göra med en array eller någon iterativ datastruktur som du kan använda för att innehålla panelerna.
panels = new Array(4).fill({ active: false });
closeOtherPopups(index) {
this.panels = this.panels.map((panel, idx) => (
{ active: idx === index }
));
}
Se detta i aktion här: https://stackblitz.com/edit/angular-u96ssk?file=src/app/app.component.ts
