javascript - Angular Material Table: jak předat/odeslat vybrané řádky po kliknutí na tlačítko?
Existuje podobná otázka Jak předat vybranou hodnotu řádku tabulky při kliknutí na tlačítko - Material Design - Angular 6, nicméně řešení tam uvedená mi v mém případě nepřipadají užitečná.
Používám tabulku Angular Material k zobrazení svých dat, u každého řádku dat mám zaškrtávací políčko pro výběr.
To, čeho se snažím dosáhnout, je, aby uživatel mohl vybrat požadované řádky a po stisknutí tlačítka budou všechny vybrané řádky předány backendu k zpracování. Momentálně je můj přístup takový, že když je zaškrtnuto políčko, zavolá se funkce (click)="onSelectCheckbox(row)" v mém component.ts a tento řádek se přidá do pole, a když uživatel řádek odznačí, vyvolá se stejná funkce a objekt řádku se odstraní pomocí .filter().
To funguje dobře, pokud klikám na zaškrtávací políčko poměrně normálním tempem, ale logika začne selhávat, když opakovaně klikám na různá zaškrtávací políčka rychlejším tempem. Při odeslání tlačítka moje konzole ukazuje, že řádky, které nejsou zaškrtnuté, jsou stále v poli, a řádky, které jsou zaškrtnuté, v poli nejsou.
Mám toto zaškrtávací políčko ve své mat-table:
<ng-container matColumnDef="select">
<th mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="$event ? masterToggle() : null" [checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()" [aria-label]="checkboxLabel()">
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let row">
<mat-checkbox (click)="onSelectCheckbox(row)" (change)="$event ? selection.toggle(row) : null"
[checked]="selection.isSelected(row)" [aria-label]="checkboxLabel(row)">
</mat-checkbox>
</td>
</ng-container>
.
.
.
<button class="btn btn-primary" (click)="openSubmitConfirmation()">Submit</button>
a logiku onSelectCheckbox(row) v mém component.ts stejně jako mé tlačítko pro testování a zobrazení vybraných řádků v konzoli:
selectedPayment = new Array<Payment>();
onSelectCheckbox(row: Payment) {
if (this.selectedPayment === undefined || this.selectedPayment.length === 0) {
this.selectedPayment.push(row);
} else if (this.selectedPayment.includes(row)) {
this.selectedPayment = this.selectedPayment.filter(
x => x.payment_reference !== row.payment_reference);
} else {
this.selectedPayment.push(row);
}
}
openSubmitConfirmation() {
console.log(this.selectedPayment);
}
Jsem si jistý, že existuje lepší a chytřejší způsob, jak to udělat, ale nenašel jsem žádné užitečné zdroje, jak to provést, každá rada by byla oceněna.
Odpověď č. 1
pro získání všech vybraných prvků najednou můžete použít SelectionModel
SelectionModel z @angular/cdk/collections
Tady jsem vytvořil Stackblitz, zkontrolujte to https://stackblitz.com/edit/angular-jlk4vf-spkxv2