【发布时间】:2022-08-11 01:17:07
【问题描述】:
我有一个 MatTable 可以在基础数据更改/添加/删除时正确加载和刷新,我遇到的唯一问题是单击其中一个标题时它没有排序,出现小箭头图标但没有变化。我在 html 中对 Observable 使用条件,并在 ngOnInit() 中设置了排序,但我尝试过的所有操作都不会触发任何排序。我找不到任何同时执行异步管道和 matSort 的示例,其中有很多示例。任何见解将不胜感激。
html:
<mat-card-header layout=\"row\">
<mat-card-title style=\"margin-bottom: 4vh\">
<span>{{ msg }}</span>
</mat-card-title>
</mat-card-header>
<mat-card-content>
<table
*ngIf=\"expenseDataSource$ | async as expenses\"
mat-table
[dataSource]=\"expenses\"
matSort
matSortDisableClear
#expTbSort=\"matSort\"
class=\"mat-elevation-z8\"
>
<ng-container matColumnDef=\"id\">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
<div class=\"center-header\" style=\"width: 50%\">Expense</div>
</th>
<td mat-cell *matCellDef=\"let element\">{{ element.id }}</td>
</ng-container>
<!-- Date Column -->
<ng-container matColumnDef=\"dateincurred\">
<th
mat-header-cell
*matHeaderCellDef
mat-sort-header
>
<div class=\"center-header\">Expense Date</div>
</th>
<td mat-cell *matCellDef=\"let element\">{{ element.dateincurred }}</td>
</ng-container>
<!-- Employee Id Column -->
<ng-container matColumnDef=\"employeeid\">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
<div class=\"center-header\">Employee</div>
</th>
<td mat-cell *matCellDef=\"let element\">{{ element.employeeid }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>
<tr
mat-row
*matRowDef=\"let row; columns: displayedColumns\"
(click)=\"select(row)\"
></tr>
</table>
<div class=\"padtop15\">
<mat-icon
(click)=\"newExpense()\"
matTooltip=\"Add New Expense\"
class=\"addicon\"
color=\"primary\"
>
control_point
</mat-icon>
</div>
</mat-card-content>
</mat-card>
<mat-card *ngIf=\"!hideEditForm\">
<mat-card-header layout=\"row\">
<mat-card-title
><span>{{ msg }}</span></mat-card-title
>
</mat-card-header>
<mat-card-content>
<app-expense-detail
[selectedExpense]=\"expense\"
[employees]=\"employees$ | async\"
(cancelled)=\"cancel(\'cancelled\')\"
(saved)=\"save($event)\"
(deleted)=\"delete($event)\"
>
</app-expense-detail>
</mat-card-content>
</mat-card>
ts:
import { Component, OnInit, ViewChild } from \'@angular/core\';
import { MatTableDataSource } from \'@angular/material/table\';
import { MatSort, Sort } from \'@angular/material/sort\';
import { Expense } from \'@app/expense/expense\';
import { Employee } from \'@app/employee/employee\';
import { EmployeeService } from \'@app/employee/employeev3.service\';
import { ExpenseService } from \'@app/expense/expense.service\';
import { Observable } from \'rxjs\';
import { catchError, tap, map } from \'rxjs/operators\';
@Component({
selector: \'app-expense\',
templateUrl: \'expense-home.component.html\',
})
export class ExpenseHomeComponent implements OnInit {
employees$?: Observable<Employee[]>;
expenses: Expense[];
expenses$?: Observable<Expense[]>;
expenseDataSource$: Observable<MatTableDataSource<Expense>> | undefined;
expense: Expense;
hideEditForm: boolean;
initialLoad: boolean;
msg: string;
todo: string;
url: string;
size: number = 0;
displayedColumns: string[] = [\'id\', \'dateincurred\', \'employeeid\'];
@ViewChild(\'expTbSort\') expTbSort = new MatSort();
constructor(
private employeeService: EmployeeService,
private expenseService: ExpenseService
) {
this.hideEditForm = true;
this.initialLoad = true;
this.expenses = [];
this.expense = {
id: 0,
employeeid: 0,
categoryid: \'\',
description: \'\',
amount: 0.0,
dateincurred: \'\',
receipt: false,
receiptscan: \'\',
};
this.msg = \'\';
this.todo = \'\';
this.url = \'\';
} // constructor
ngOnInit(): void {
this.msg = \'loading expenses from server...\';
this.expenses$ = this.expenseService.get();
this.expenseDataSource$ = this.expenses$.pipe(
map((expenses) => {
const dataSource = new MatTableDataSource<Expense>(expenses);
// dataSource.data = expenses;
dataSource.sort = this.expTbSort;
return dataSource;
}),
tap(() => {
this.employees$ = this.employeeService.get();
if (this.initialLoad === true) {
this.msg = \'expenses and employees loaded!\';
this.initialLoad = false;
}
})
);
}
select(selectedExpense: Expense): void {
this.todo = \'update\';
this.expense = selectedExpense;
this.msg = `Expense ${selectedExpense.id} selected`;
this.hideEditForm = !this.hideEditForm;
} // select
/**
* cancelled - event handler for cancel button
*/
cancel(msg?: string): void {
this.hideEditForm = !this.hideEditForm;
this.msg = \'operation cancelled\';
} // cancel
/**
* update - send changed update to service update local array
*/
update(selectedExpense: Expense): void {
this.expenseService.update(selectedExpense).subscribe({
// Create observer object
next: (exp: Expense) => (this.msg = `Expense ${exp.id} updated!`),
error: (err: Error) => (this.msg = `Update failed! - ${err.message}`),
complete: () => {
this.hideEditForm = !this.hideEditForm;
},
});
} // update
/**
* save - determine whether we\'re doing and add or an update
*/
save(expense: Expense): void {
expense.id ? this.update(expense) : this.add(expense);
} // save
/**
* add - send expense to service, receive newid back
*/
add(newExpense: Expense): void {
this.msg = \'Adding expense...\';
newExpense.id = 0;
this.expenseService.add(newExpense).subscribe({
// Create observer object
next: (exp: Expense) => {
this.msg = `Expense ${exp.id} added!`;
},
error: (err: Error) => (this.msg = `Expense not added! - ${err.message}`),
complete: () => {
this.hideEditForm = !this.hideEditForm;
},
});
} // add
/**
* newExpense - create new expense instance
*/
newExpense(): void {
this.expense = {
id: 0,
employeeid: 0,
categoryid: \'\',
description: \'\',
amount: 0.0,
dateincurred: \'\',
receipt: false,
receiptscan: \'\',
};
this.msg = \'New expense\';
this.hideEditForm = !this.hideEditForm;
} // newExpense
/**
* delete - send expense id to service for deletion
*/
delete(selectedExpense: Expense): void {
this.expenseService.delete(selectedExpense.id).subscribe({
// Create observer object
next: (numOfExpensesDeleted: number) => {
numOfExpensesDeleted === 1
? (this.msg = `Expense ${selectedExpense.id} deleted!`)
: (this.msg = `Expense ${selectedExpense.id} not deleted!`);
},
error: (err: Error) => (this.msg = `Delete failed! - ${err.message}`),
complete: () => {
this.hideEditForm = !this.hideEditForm;
},
});
}
} // ExpenseHomeComponent
标签: angular sorting asynchronous angular-material angular2-observables