Angular自定义appSort指令绑定MatTableDataSource出现类型缺失报错
问题根因
你自定义的SortDirective里@Input() appSort的类型被声明为ContactListEntry(单条数据对象类型),但你模板里传入的是MatTableDataSource(Angular Material表格的数据源实例类型),类型不匹配导致编译报错。
方案1:修改自定义指令适配现有逻辑
如果你要继续用自己写的Sort工具类的排序逻辑,按如下步骤修改:
第一步:修改指令的Input类型
在SortDirective中引入MatTableDataSource依赖,调整appSort的类型定义:
import { MatTableDataSource } from '@angular/material/table'; // 新增引入 import { Directive, Input, Renderer2, ElementRef, HostListener } from '@angular/core'; import { ContactListEntry } from '../contact-list-entry'; import { Sort } from '../data-service'; @Directive({ selector: '[appSort]' }) export class SortDirective { // 把原来的ContactListEntry类型改成MatTableDataSource泛型类型 @Input() appSort: MatTableDataSource<ContactListEntry>; constructor(private renderer: Renderer2, private targetElement: ElementRef) { } // ...其他代码 }
第二步:调整排序调用逻辑
MatTableDataSource的排序通过修改内部data数组实现,调整sortData方法如下:
@HostListener("click") sortData(){ const sort = new Sort(); const elem = this.targetElement.nativeElement; const order = elem.getAttribute("data-order") === "desc" ? "desc" : "asc"; const type = elem.getAttribute("data-type") || ""; const property = elem.getAttribute("data-name") || ""; // 对数据源的data数组执行排序后重新赋值触发视图更新 this.appSort.data = this.appSort.data.sort(sort.startSort(property, order, type)); // 切换排序方向标记 elem.setAttribute("data-order", order === "desc" ? "asc" : "desc"); }
第三步:模板保留现有写法即可,无需修改。
方案2:配合Angular Material自带的MatSort实现(更规范,无需维护自定义排序逻辑)
Angular Material的MatTable本身提供了成熟的排序能力,不需要自行开发排序指令,按如下配置即可:
第一步:组件中绑定MatSort实例到数据源
import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { ContactListEntry } from '../contact-list-entry'; export class YourComponent implements AfterViewInit { dataSource = new MatTableDataSource<ContactListEntry>([]); @ViewChild(MatSort) sort!: MatSort; ngAfterViewInit() { // 绑定排序实例到数据源 this.dataSource.sort = this.sort; // 可选:自定义排序字段映射,适配特殊字段/类型的排序逻辑 this.dataSource.sortingDataAccessor = (item: ContactListEntry, property: string) => { switch(property) { case 'employeeId': return item.employeeId; // 其他自定义字段映射可在此处扩展 default: return (item as any)[property]; } }; } }
第二步:调整模板配置
<!-- 表格标签上添加matSort指令 --> <table mat-table [dataSource]="dataSource" matSort> <ng-container matColumnDef="id"> <!-- 去掉自定义的appSort、data-order、data-name属性,直接用mat-sort-header指定排序字段 --> <th mat-header-cell *matHeaderCellDef mat-sort-header="employeeId">ID</th> <td mat-cell *matCellDef="let formular">{{formular.id}}</td> </ng-container> <!-- 其他列配置 --> </table>
该方案不需要维护之前的Sort工具类和SortDirective,性能和兼容性更优,是Angular Material官方推荐的排序实现方式。
内容的提问来源于stack exchange,提问作者max_flu
相关产品推荐
相关产品推荐

