区分材料手风琴。

huangapple go评论62阅读模式
英文:

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

&lt;mat-accordion&gt;
    &lt;mat-expansion-panel (opened)=&quot;data.panelOpenState === true&quot; (closed)=&quot;data.panelOpenState === false&quot; [expanded]=&quot;data.expanded&quot;&gt;
        &lt;mat-expansion-panel-header (click)=&quot;stateValue()&quot;&gt;
            &lt;mat-panel-title&gt;
                {{ data?.title }}
            &lt;/mat-panel-title&gt;
        &lt;/mat-expansion-panel-header&gt;
        &lt;ng-content&gt;&lt;/ng-content&gt;
    &lt;/mat-expansion-panel&gt;
&lt;/mat-accordion&gt;

Mat accordion TS

import { Component, Input, OnInit } from &#39;@angular/core&#39;;
import { SidePanelAccordianData } from &#39;./side-panel-accordian.model&#39;;
import { SidePanelAccordianService } from &#39;./side-panel-accordian.service&#39;;

@Component({
  selector: &#39;app-side-panel-accordian&#39;,
  templateUrl: &#39;./side-panel-accordian.component.html&#39;,
  styleUrls: [&#39;./side-panel-accordian.component.scss&#39;]
})
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 &#39;@angular/core&#39;;
import { BehaviorSubject, Observable, Subject } from &#39;rxjs&#39;;

@Injectable({
  providedIn: &#39;root&#39;
})
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 = &#39;&#39;;
  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

&lt;app-side-panel-accordian [data]=&quot;{title:&#39;Title&#39;, panelOpenState: panelOpenState, expanded: firstDriverExpanded}&quot;&gt;
    &lt;div class=&quot;inner-row-data&quot;&gt;
      &lt;form-input [formStatus]=&quot;formStatus&quot; [parentFormGroup]=&quot;setupForm&quot; [data]=&quot;{
        formControlName: &#39;firstDriverName&#39;,
        name: &#39;firstDriverName&#39;,
      }&quot; (onBlur)=&quot;setFirstDriverDetails(&#39;name&#39;)&quot;&gt;
      &lt;/form-input&gt;
    &lt;/div&gt;
&lt;/app-side-panel-accordian&gt;

&lt;app-side-panel-accordian [data]=&quot;{title:&#39;Title&#39;, panelOpenState: panelOpenState, expanded: secondDriverExpanded}&quot;&gt;
    &lt;div class=&quot;inner-row-data&quot;&gt;
      &lt;form-input [formStatus]=&quot;formStatus&quot; [parentFormGroup]=&quot;setupForm&quot; [data]=&quot;{
        formControlName: &#39;secondDriverName&#39;,
        name: &#39;secondDriverName&#39;,
      }&quot; (onBlur)=&quot;setSecondDriverDetails(&#39;name&#39;)&quot;&gt;
      &lt;/form-input&gt;
    &lt;/div&gt;
&lt;/app-side-panel-accordian&gt;

TS

this.accordianStateService.openState$.subscribe(data =&gt;{
  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$值时区分手风琴,您可以按照以下方式修改您的代码:

  1. 更新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;
  }
}
  1. 修改SidePanelAccordianComponent以在状态更改时发出手风琴的标识符。将stateValue()方法更新如下:
stateValue() {
  this.data.panelOpenState = !this.data.panelOpenState;
  this.accordianStateService.setOpenState({ id: this.data.id, state: this.data.panelOpenState });
}
  1. 更新SidePanelAccordianService以在状态更改时发出手风琴的标识符。将setOpenState()方法更新如下:
public setOpenState(data: { id: string, state: boolean }) {
  this._openStateBehaviorSubject.next(data);
}
  1. 在使用包装器的组件中,订阅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:

  1. Update the SidePanelAccordianData model to include an identifier for each accordion. For example:
export class SidePanelAccordianData {
  public id: string;
  public title: string = &#39;&#39;;
  public panelOpenState: boolean;
  public expanded: boolean;

  constructor(args) {
    this.id = args.id;
    this.title = args.title;
    this.panelOpenState = args.panelOpenState;
    this.expanded = args.expanded;
  }
}
  1. Modify the SidePanelAccordianComponent to emit the accordion's identifier along with the state change. Update the stateValue() method as follows:
stateValue() {
  this.data.panelOpenState = !this.data.panelOpenState;
  this.accordianStateService.setOpenState({ id: this.data.id, state: this.data.panelOpenState });
}
  1. Update the SidePanelAccordianService to emit the accordion's identifier along with the state change. Update the setOpenState() method as follows:
public setOpenState(data: { id: string, state: boolean }) {
  this._openStateBehaviorSubject.next(data);
}
  1. 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 =&gt; {
  const accordionId = data.id;
  const accordionState = data.state;

  if (accordionId === &#39;firstAccordionId&#39;) {
    // Handle state change for the first accordion
    this.firstDriverExpanded = accordionState;
  } else if (accordionId === &#39;secondAccordionId&#39;) {
    // Handle state change for the second accordion
    this.secondDriverExpanded = accordionState;
  }
});

Make sure to replace &#39;firstAccordionId&#39; and &#39;secondAccordionId&#39; 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.

huangapple
  • 本文由 发表于 2023年6月19日 15:06:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76504332.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定