英文:
Differentiate between mat accordions
问题
我有一个用于Angular Material中mat accordion组件的包装器。我尝试区分用户单击特定手风琴时的不同手风琴。
这是我的代码
包装器
Mat accordion HTML
<mat-accordion>
<mat-expansion-panel (opened)="data.panelOpenState === true" (closed)="data.panelOpenState === false" [expanded]="data.expanded">
<mat-expansion-panel-header (click)="stateValue()">
<mat-panel-title>
{{ data?.title }}
</mat-panel-title>
</mat-expansion-panel-header>
<ng-content></ng-content>
</mat-expansion-panel>
</mat-accordion>
Mat accordion TS
import { Component, Input, OnInit } from '@angular/core';
import { SidePanelAccordianData } from './side-panel-accordian.model';
import { SidePanelAccordianService } from './side-panel-accordian.service';
@Component({
selector: 'app-side-panel-accordian',
templateUrl: './side-panel-accordian.component.html',
styleUrls: ['./side-panel-accordian.component.scss']
})
export class SidePanelAccordianComponent implements OnInit {
@Input() data: SidePanelAccordianData;
panelOpenState;
constructor(private accordianStateService: SidePanelAccordianService) { }
ngOnInit(): void {
}
stateValue() {
this.data.panelOpenState = !this.data.panelOpenState;
this.accordianStateService.setOpenState(this.data.panelOpenState);
}
}
Mat accordion Service
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable, Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class SidePanelAccordianService {
private _openStateBehaviorSubject = new BehaviorSubject(false);
public openState$ = this._openStateBehaviorSubject.asObservable();
public setOpenState(value: boolean) {
this._openStateBehaviorSubject.next(value);
}
}
Mat accordion model
export class SidePanelAccordianData {
public title: string = '';
public panelOpenState: boolean;
public expanded: boolean;
constructor(args) {
this.title = args.title;
this.panelOpenState = args.panelOpenState;
this.expanded = args.expanded;
}
}
使用包装器的组件
HTML
<app-side-panel-accordian [data]="{title:'Title', panelOpenState: panelOpenState, expanded: firstDriverExpanded}">
<div class="inner-row-data">
<form-input [formStatus]="formStatus" [parentFormGroup]="setupForm" [data]="{
formControlName: 'firstDriverName',
name: 'firstDriverName',
}" (onBlur)="setFirstDriverDetails('name')">
</form-input>
</div>
</app-side-panel-accordian>
<app-side-panel-accordian [data]="{title:'Title', panelOpenState: panelOpenState, expanded: secondDriverExpanded}">
<div class="inner-row-data">
<form-input [formStatus]="formStatus" [parentFormGroup]="setupForm" [data]="{
formControlName: 'secondDriverName',
name: 'secondDriverName',
}" (onBlur)="setSecondDriverDetails('name')">
</form-input>
</div>
</app-side-panel-accordian>
TS
this.accordianStateService.openState$.subscribe(data => {
this.accordianState = data;
if(!this.accordianState) {
this.firstDriverExpanded = false;
this.secondDriverExpanded = false;
}
});
因此,正如您在使用mat accordion包装器的组件中所看到的,我可以拥有多个手风琴,所以我的问题是,当this.accordianStateService.openState$
的值在单击时更新时,我如何区分这些手风琴?
我需要区分它们的原因是因为我有规则,规定了何时打开或关闭特定的手风琴。
英文:
I have a wrapper for the mat accordion component in angular material. I am trying to differentiate between the different accordions when a user clicks on a specific accordion.
Here is my code
Wrapper
Mat accordion HTML
<mat-accordion>
<mat-expansion-panel (opened)="data.panelOpenState === true" (closed)="data.panelOpenState === false" [expanded]="data.expanded">
<mat-expansion-panel-header (click)="stateValue()">
<mat-panel-title>
{{ data?.title }}
</mat-panel-title>
</mat-expansion-panel-header>
<ng-content></ng-content>
</mat-expansion-panel>
</mat-accordion>
Mat accordion TS
import { Component, Input, OnInit } from '@angular/core';
import { SidePanelAccordianData } from './side-panel-accordian.model';
import { SidePanelAccordianService } from './side-panel-accordian.service';
@Component({
selector: 'app-side-panel-accordian',
templateUrl: './side-panel-accordian.component.html',
styleUrls: ['./side-panel-accordian.component.scss']
})
export class SidePanelAccordianComponent implements OnInit {
@Input() data: SidePanelAccordianData;
panelOpenState;
constructor(private accordianStateService: SidePanelAccordianService) { }
ngOnInit(): void {
}
stateValue() {
this.data.panelOpenState = !this.data.panelOpenState;
this.accordianStateService.setOpenState(this.data.panelOpenState);
}
}
Mat accordion Service
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable, Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class SidePanelAccordianService {
private _openStateBehaviorSubject = new BehaviorSubject(false);
public openState$ = this._openStateBehaviorSubject.asObservable();
public setOpenState(value: boolean) {
this._openStateBehaviorSubject.next(value);
}
}
Mat accordion model
export class SidePanelAccordianData {
public title: string = '';
public panelOpenState: boolean;
public expanded: boolean;
constructor(args) {
this.title = args.title;
this.panelOpenState = args.panelOpenState;
this.expanded = args.expanded;
}
}
Component where I am using the wrapper
HTML
<app-side-panel-accordian [data]="{title:'Title', panelOpenState: panelOpenState, expanded: firstDriverExpanded}">
<div class="inner-row-data">
<form-input [formStatus]="formStatus" [parentFormGroup]="setupForm" [data]="{
formControlName: 'firstDriverName',
name: 'firstDriverName',
}" (onBlur)="setFirstDriverDetails('name')">
</form-input>
</div>
</app-side-panel-accordian>
<app-side-panel-accordian [data]="{title:'Title', panelOpenState: panelOpenState, expanded: secondDriverExpanded}">
<div class="inner-row-data">
<form-input [formStatus]="formStatus" [parentFormGroup]="setupForm" [data]="{
formControlName: 'secondDriverName',
name: 'secondDriverName',
}" (onBlur)="setSecondDriverDetails('name')">
</form-input>
</div>
</app-side-panel-accordian>
TS
this.accordianStateService.openState$.subscribe(data =>{
this.accordianState = data;
if(!this.accordianState) {
this.firstDriverExpanded = false;
this.secondDriverExpanded = false;
}
});
So as you can see in the component above where I use the mat accordion wrapper I can have more than one accordion so my question is how will I differentiate between the accordions when the this.accordianStateService.openState$
value is updated on click?
The reason I need to differentiate is because i have rules as to when a certain accordion is open or closed.
答案1
得分: 0
为了在更新openState$
值时区分手风琴,您可以按照以下方式修改您的代码:
- 更新
SidePanelAccordianData
模型以包括每个手风琴的标识符。例如:
export class SidePanelAccordianData {
public id: string;
public title: string = '';
public panelOpenState: boolean;
public expanded: boolean;
constructor(args) {
this.id = args.id;
this.title = args.title;
this.panelOpenState = args.panelOpenState;
this.expanded = args.expanded;
}
}
- 修改
SidePanelAccordianComponent
以在状态更改时发出手风琴的标识符。将stateValue()
方法更新如下:
stateValue() {
this.data.panelOpenState = !this.data.panelOpenState;
this.accordianStateService.setOpenState({ id: this.data.id, state: this.data.panelOpenState });
}
- 更新
SidePanelAccordianService
以在状态更改时发出手风琴的标识符。将setOpenState()
方法更新如下:
public setOpenState(data: { id: string, state: boolean }) {
this._openStateBehaviorSubject.next(data);
}
- 在使用包装器的组件中,订阅
openState$
并根据其标识符区分手风琴:
this.accordianStateService.openState$.subscribe(data => {
const accordionId = data.id;
const accordionState = data.state;
if (accordionId === 'firstAccordionId') {
// 处理第一个手风琴的状态更改
this.firstDriverExpanded = accordionState;
} else if (accordionId === 'secondAccordionId') {
// 处理第二个手风琴的状态更改
this.secondDriverExpanded = accordionState;
}
});
确保将'firstAccordionId'
和'secondAccordionId'
替换为您手风琴的实际标识符。
通过这种方法,在更新openState$
值时,您可以根据它们的标识符区分手风琴,从而能够分别处理每个手风琴的状态更改。
英文:
To differentiate between the accordions when the openState$
value is updated, you can modify your code as follows:
- Update the
SidePanelAccordianData
model to include an identifier for each accordion. For example:
export class SidePanelAccordianData {
public id: string;
public title: string = '';
public panelOpenState: boolean;
public expanded: boolean;
constructor(args) {
this.id = args.id;
this.title = args.title;
this.panelOpenState = args.panelOpenState;
this.expanded = args.expanded;
}
}
- Modify the
SidePanelAccordianComponent
to emit the accordion's identifier along with the state change. Update thestateValue()
method as follows:
stateValue() {
this.data.panelOpenState = !this.data.panelOpenState;
this.accordianStateService.setOpenState({ id: this.data.id, state: this.data.panelOpenState });
}
- Update the
SidePanelAccordianService
to emit the accordion's identifier along with the state change. Update thesetOpenState()
method as follows:
public setOpenState(data: { id: string, state: boolean }) {
this._openStateBehaviorSubject.next(data);
}
- In the component where you use the wrapper, subscribe to
openState$
and differentiate between the accordions based on their identifiers:
this.accordianStateService.openState$.subscribe(data => {
const accordionId = data.id;
const accordionState = data.state;
if (accordionId === 'firstAccordionId') {
// Handle state change for the first accordion
this.firstDriverExpanded = accordionState;
} else if (accordionId === 'secondAccordionId') {
// Handle state change for the second accordion
this.secondDriverExpanded = accordionState;
}
});
Make sure to replace 'firstAccordionId'
and 'secondAccordionId'
with the actual identifiers of your accordions.
With this approach, you can differentiate between the accordions based on their identifiers when the openState$
value is updated, allowing you to handle the state changes for each accordion separately.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论