angular - MatTable Utvid/Sammenknepp-ikon problem ved paginering og sortering
Jeg har en Angular Material-tabell som bruker detailRow-direktivet for å sette inn en detalj-/søster-rad ved siden av en tabellrad.
StackBlitz
Jeg ønsket å gi det et utseende av at raden utvides eller kollapser, så jeg la til et par ikoner som blir slått av og på når cellen som inneholder dem klikkes.
<mat-header-cell *matHeaderCellDef> Action </mat-header-cell>
<mat-cell *matCellDef="let element">
<button mat-icon-button color="primary" (click)="element[i] = !element[i]">
<mat-icon id="expand_more" #expand_more *ngIf="!element[i] " >expand_more</mat-icon>
<mat-icon id="expand_less" #expand_less *ngIf="element[i] ">expand_less</mat-icon>
</button>
</mat-cell>
Men hvis jeg lar raden være utvidet og går til neste side eller sorterer, bytter ikke ikonene fordi det ikke finnes noen måte for dem å bli byttet på.
Jeg har prøvd å koble meg til page-hendelsen eller sortChange-hendelsen, men fikk ingenting.
Jeg er klar over at det finnes en ny måte å gjøre utvid/skjul på i Angular Material v7 som sannsynligvis fungerer bra med paginering og sortering, men det vil ta en stund før jeg oppgraderer. I mellomtiden, har noen noen ideer om hvordan man kan løse dette?
Svar #1
Kort svar
I cdk-detail-row.directive.ts legg til dette
ngOnDestroy(): void {
this.row[undefined] = false;
}
Langt svar
For det første fanger du klikk på to steder, en gang i mat-row og den andre i mat-cell (å klikke på ikonet utløser begge hendelsene. Å klikke andre steder på raden utløser bare onToggleChange). Og også dette element[i]=!element[i] er en hack - (variabelen i er udefinert). Så hvis du klikker andre steder på raden, endres ikke utvidelsesikonet, dette er grunnen til at jeg ble forvirret, da jeg trodde det ikke skulle endres. Eksemplet vil bare fjerne klikket på mat-cell for å gjøre det enkelt.
I table-basic-example.html bør du fjerne (click)-outputen fra den og legge til rad-argumentet i metoden onToggleChange($event, row). Og endre *ng-if til å lytte til element.close i stedet
<ng-container matColumnDef="expandCollapse">
<mat-header-cell *matHeaderCellDef> Action </mat-header-cell>
<mat-cell *matCellDef="let element">
<button mat-icon-button color="primary">
<mat-icon id="expand_more" #expand_more *ngIf="!element.close" >expand_more</mat-icon>
<mat-icon id="expand_less" #expand_less *ngIf="element.close">expand_less</mat-icon>
</button>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"
class="element-row"
[cdkDetailRow]="row" [cdkDetailRowTpl]="tpl"
(toggleChange)="onToggleChange($event, row)">
</mat-row>
tabell-grunnleggende-eksempel.ts
Legg til close-egenskapen i grensesnittet element
export interface Element {
name: string;
position: number;
weight: number;
symbol: string;
close?: boolean;
}
Nå vil vi håndtere lukking og åpning av raden i metoden onToggleChange.
onToggleChange(cdkDetailRow: CdkDetailRowDirective, row: Element): void {
if (this.singleChildRowDetail && this.openedRow && this.openedRow.expended) {
this.openedRow.toggle();
}
if (!row.close) {
row.close = true;
} else {
row.close = false;
}
this.openedRow = cdkDetailRow.expended ? cdkDetailRow : undefined;
}
Til slutt, i cdk-detail-row.directive.ts vil vi ønske å lukke raden når direktivet blir ødelagt av paginering eller ved å bytte bort. Så vi vil implementere onDestroy-metoden
export class CdkDetailRowDirective implements OnDestroy{
...Details of implementation.....
}
Den nye ngOnDestroy-metoden bør se slik ut
ngOnDestroy(): void {
this.row.close = false;
}