告诉我为什么在表格中排序不起作用,我按照Angular Material官方文档中的示例做所有事情
模板代码:
<h5 class="card-title">****************</h5>
<table mat-table [dataSource]="tabledata" matSort *ngIf="isLoaded">
<ng-container matColumnDef="Фамилия, имя, отчество">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Фамилия, имя, отчество </th>
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
</ng-container>
<ng-container matColumnDef="скилл P">
<th mat-header-cell *matHeaderCellDef mat-sort-header> скилл P </th>
<td mat-cell *matCellDef="let element"> {{element.skillP}} </td>
</ng-container>
<ng-container matColumnDef="скилл A">
<th mat-header-cell *matHeaderCellDef mat-sort-header> скилл A </th>
<td mat-cell *matCellDef="let element"> {{element.skillA}} </td>
</ng-container>
<ng-container matColumnDef="скилл E">
<th mat-header-cell *matHeaderCellDef mat-sort-header> скилл E </th>
<td mat-cell *matCellDef="let element"> {{element.skillE}} </td>
</ng-container>
<ng-container matColumnDef="скилл I">
<th mat-header-cell *matHeaderCellDef mat-sort-header> скилл I </th>
<td mat-cell *matCellDef="let element"> {{element.skillI}} </td>
</ng-container>
<ng-container matColumnDef="Подразделение">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Подразделение </th>
<td mat-cell *matCellDef="let element"> {{element.department}} </td>
</ng-container>
<ng-container matColumnDef="Должность">
<th mat-header-cell *matHeaderCellDef> Должность </th>
<td mat-cell *matCellDef="let element"> {{element.position}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
这是组件代码:
import { Component, OnInit, ViewChild } from '@angular/core';
import { Subscription, combineLatest } from 'rxjs';
import { PersonsService } from 'src/app/shared/services/persons.service';
import { PaeiService } from 'src/app/shared/services/paei.service';
import { Paei } from 'src/app/assessment/paei-test/models/paei.model';
import { Person } from 'src/app/shared/models/person.model';
import { MatTableDataSource, MatSort } from '@angular/material';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'mvv-paei-table',
templateUrl: './paei-table.component.html',
styleUrls: ['./paei-table.component.scss']
})
export class PaeiTableComponent implements OnInit {
sub: Subscription;
personsList: Person[] = [];
paeiList: Paei[] = [];
persons: {
name: string,
skillP: number,
skillA: number,
skillE: number,
skillI: number,
department: string,
position: string
}[] = [];
tabledata: any;
public displayedColumns = [
'Фамилия, имя, отчество',
'скилл P',
'скилл A',
'скилл E',
'скилл I',
'Подразделение',
'Должность'
];
isLoaded = false;
constructor(
private personsService: PersonsService,
private paeiService: PaeiService,
) { }
@ViewChild(MatSort) sort: MatSort;
ngOnInit() {
this.sub = combineLatest(
this.personsService.getPersons(),
this.paeiService.getAllPaei()
).subscribe(value => {
value[0].forEach(doc => {
const person = new Person(
doc.data().name,
doc.data().middleName,
doc.data().surname,
doc.data().gender,
doc.data().date,
doc.data().position,
doc.data().department,
doc.id
);
this.personsList.push(person);
});
value[1].forEach(doc => {
const paei = new Paei(
doc.data().id,
doc.data().date,
doc.data().skillP,
doc.data().skillA,
doc.data().skillE,
doc.data().skillI,
doc.data().isReaded
);
this.paeiList.push(paei);
});
for (let i = 0; i < this.paeiList.length; i++) {
const pers = this.personsList.filter(
res => res.personId === this.paeiList[i].id);
const name = pers[0].surname + ' ' + pers[0].name + ' ' + pers[0].middleName;
this.persons.push(
{
name: name,
skillP: this.paeiList[i].skillP,
skillA: this.paeiList[i].skillA,
skillE: this.paeiList[i].skillE,
skillI: this.paeiList[i].skillI,
department: pers[0].department,
position: pers[0].position
}
);
this.tabledata = new MatTableDataSource(this.persons);
}
this.isLoaded = true;
setTimeout(() => {
this.tabledata.sort = this.sort;
console.log('проверка сортировки', this.sort);
}, 1000);
});
}
}
不要注意超时。
您没有完全遵循该示例,因为您使用
ngIf的是指令:)我会假设你已经导入了
MatSortModule,所以我会立即描述你的问题。当您使用装饰器
@ViewChild时,您是在告诉编译器生成一个特定的数据结构,称为NodeDef(节点定义)。在运行时,Angular 不只是构建一个 DOM 树,还为你设置所有必要的类属性,你可以用它们来装饰@Input() | @ViewChild() | @HostBinding()等等。在您的示例中,在第一个更改检测机制期间,Angular 调用一个函数
checkAndUpdateQuery来设置用@ViewChild() | @ViewChildren() | @ContentChild() | @ContentChildren(). 整个问题是元素table被包裹ng-template(由于使用了指令ngIf),并且在初始阶段也是isLoaded相等false的,因此Angular无法物理访问指令实例MatSort(因为它尚未创建)并设置属性. 此外,元素本身被table异步投影到 DOM 中。sort要验证这一点 -在钩子中输出到控制台ngOnInit:有2种方法可以解决这个问题:
1)使用属性
hidden而不是指令ngIf:2) 在构造函数中注入对视图的引用,并在设置属性后运行更改检测机制
isLoaded = true,这又会再次调用checkAndUpdateQuery将为您设置属性的函数sort:你有一个指令,
*ngIf它不适用于它。尝试将其替换为<table>mat-sort[hidden]="!isLoaded"