Reputation: 1986
Im pushing dynamically added componnets to an array "elements"
this.elements.push({ view, component });
Each of the components has a mat-expansion-panel like:
<mat-expansion-panel fxFlex="100" [expanded]="!closed" (opened)="emitOpened()" >
Inside each of these components there is an Input() closed and an event emitter panelOpened emitted when the panel is opened:
emitOpened() {
this.panelOpened.emit();
}
When one of these component's expansion panel is opened , the panels of all other components should get closed .
closeOtherQuestions() {
this.elements
.map((el) => el.component)
.forEach((c) => {
c.panelOpened.subscribe((open) => {
this.elements
.map((el) => el.component)
.filter((item) => item !== c)
.forEach((item) => (item.closed = true));
});
});
}
Im trying to pass in closed after subscribing to the output event of each of these components .Right now its not working correctly . Im seeing that the subscription is triggering multiple times as it is placed inside a forEach loop.
Upvotes: 1
Views: 452
Reputation: 9124
You could use combineLatest
in combination with pairWise
to find the element in the array which should become closed. For this approach you would need to change panelOpened
event to a expansionChanged
event which holds the current state as a boolean.
emitOpened() {
this.expansionChanged.emit(true);
}
emitClosed() {
this.expansionChanged.emit(false);
}
Now you can do
combineLatest(this.elements.map(el => el.component.expansionChanged)).pipe(
pairWise(),
map(([prev, curr]) => curr.findIndex((el, i) => el && prev[i])),
).subscribe(
index => this.elements[index].component.closed = true;
);
Upvotes: 1