angular - 可以为 Angular Material 表指定行标题吗?

标签 angular angular-material accessibility

我浏览了https://material.angular.io/components/table并可以看到如何指定列标题,但我没有看到指定行标题的方法。

从纯 html 的 Angular 来看,我希望最终得到如下结果:

<table>
  <tr>
    <th scope='col'>name</th>
    <th scope='col'>age</th>
    <th scope='col'>favorite color</th>
  </tr>
  <tr>
    <th scope='row'>fred</th>
    <td>35</td>
    <td>orange</td>
  </tr>
  <tr>
    <th scope='row'>barney</th>
    <td>32</td>
    <td>brown</td>
  </tr>
  <tr>
    <th scope='row'>wilma</th>
    <td>33</td>
    <td>white</td>
  </tr>
</table>

其中“fred”、“barney”和“wilma”是行标题。

我知道 Angular Material 不使用原生表格标签,而是使用自定义标签和 Angular 色,例如:

<div role='grid'>
  <div role='row'>
    <div role='columnheader'>name</div>
    <div role='columnheader'>age</div>
    <div role='columnheader'>favorite color</div>
  </div>
  <div role='row'>
    <div role='rowheader'>fred</div>
    <div role='gridcell'>35</div>
    <div role='gridcell'>orange</div>
  </div>
  <div role='row'>
    <div role='rowheader'>barney</div>
    <div role='gridcell'>32</div>
    <div role='gridcell'>brown</div>
  </div>
  <div role='row'>
    <div role='rowheader'>wilma</div>
    <div role='gridcell'>33</div>
    <div role='gridcell'>white</div>
  </div>
</div>    

(上面显示 <div> 元素,而不是 <mat-table><mat-header> 等,因为我希望 role= 脱颖而出)

有没有办法获取行标题?如果我调出 https://material.angular.io/components/table 中第一个表的代码检查器,

table snippet

“氢”电池定义为:

<mat-cell _ngcontent-c20="" class="mat-cell cdk-column-name mat-column-name ng-star-inserted" role="gridcell">Hydrogen</mat-cell>

如果我查看列标题“名称”,它的定义为:

<mat-header-cell _ngcontent-c20="" class="mat-header-cell cdk-column-name mat-column-name ng-star-inserted" role="columnheader">Name</mat-header-cell>

如果我将两者合并并使用 <mat-header-cell>列标题和 class 中的标记定义来自<mat-cell> (出于样式目的),并更改 role来自columnheaderrowheader ,我得到一个有效的行标题。

<mat-header-cell _ngcontent-c20="" class="mat-cell cdk-column-name mat-column-name ng-star-inserted" role="rowheader">Hydrogen</mat-header-cell>

当我使用屏幕阅读器并垂直浏览列时,会在读取表格单元格之前正确读取行标题。效果很好。我只需要一种方法来指定 Angular Material 中的行标题。

最佳答案

由于现在可以使用表标签创建 Angular 表,因此您只需在特定单元格上指定范围属性即可。另外,如果你想删除所有默认的 role属性,那么您可以使用 null 的属性绑定(bind)值[attr.role]="null" :

<table mat-table [dataSource]="dataSource">

  <ng-container matColumnDef="name">
    <th mat-header-cell *matHeaderCellDef scope="col" [attr.role]="null"> Name </th>
    <td mat-cell *matCellDef="let element" scope="row" [attr.role]="null"> {{element.name}} </td>
  </ng-container>

  <ng-container matColumnDef="age">
    <th mat-header-cell *matHeaderCellDef scope="col" [attr.role]="null"> Age </th>
    <td mat-cell *matCellDef="let element" [attr.role]="null"> {{element.age}} </td>
  </ng-container>

  <ng-container matColumnDef="favorite color">
    <th mat-header-cell *matHeaderCellDef scope="col" [attr.role]="null"> Favorite Color </th>
    <td mat-cell *matCellDef="let element" [attr.role]="null"> {{element['favorite color']}} </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns" [attr.role]="null"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;" [attr.role]="null"></tr>
</table>

这应该会导致您从纯 html Angular 获得与所需的结果相同的结果( https://www.w3.org/WAI/tutorials/tables/two-headers/ )

唯一不能以声明方式覆盖的部分是任何表部分( thead role="rowgroup"tbody role="rowgroup"tfoot role="rowgroup" ),但无论如何,如果需要删除(或更改)那些 role ,属性你可以在 ngAfterViewInit 内完成主机组件或专用指令的钩子(Hook):

@ViewChild('tableRef', { static: false, read: ElementRef }) tableRef: ElementRef<HTMLTableElement>;

ngAfterViewInit() {
  const table = this.tableRef.nativeElement;
  Array.from(table.children).forEach(section => {
    section.removeAttribute('role');
  })
}

不要忘记分配模板引用变量<table #tableRef到您的餐 table

<强> Stackblitz Example

关于angular - 可以为 Angular Material 表指定行标题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49547112/

相关文章:

angular - 如何更改 Angular Material 2 CSS 导入顺序?

订阅的 Angular 返回值

python - 有没有办法将 Python 代码中的缩进转换为大括号?

angular - 核心.js :4197 ERROR TypeError: chart_js__WEBPACK_IMPORTED_MODULE_2__ is not a constructor

javascript - 当在组件的根目录中提供服务时如何监视服务方法

angular - 有人可以解释 Angular 订阅方法吗

Angular 5 服务无法通过单元测试(NullInjectorError : No provider for HttpClient!)

css - 从 md-list-item(AngularJS Material )中删除点击行为

java - Android AccessibilityDelegate 强制读取 ViewGroup 而不是 child

html - 我需要在实际的复选框上进行 aria-checked 吗