可以为角材质表指定行标题吗?

时间:2018-03-29 02:34:12

标签: angular angular-material accessibility

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

从纯粹的html角度来看,我想最终得到类似的东西:

<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'是行标题。

我知道角度材质不使用本机表标签,而是自定义标签和角色,例如:

<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>

如果我查看列标题'Name',它定义为:

<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>定义(用于样式目的),还可以更改rolecolumnheaderrowheader,我得到一个有效的行标题。

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

当我使用屏幕阅读器并垂直浏览列时,在读取表格单元格之前正确读取行标题。它很棒。我只需要一种在角度材质中指定行标题的方法。

1 个答案:

答案 0 :(得分:3)

由于现在可以使用表标签创建Angular表,因此您只需在特定单元格上指定scope属性即可。另外,如果要删除所有默认的role属性,则可以将属性绑定与null[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角度(https://www.w3.org/WAI/tutorials/tables/two-headers/)开始,这应该会导致您获得与所需结果相同的结果

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

ngAfterViewInit

不要忘记为表分配模板引用变量@ViewChild('tableRef', { static: false, read: ElementRef }) tableRef: ElementRef<HTMLTableElement>; ngAfterViewInit() { const table = this.tableRef.nativeElement; Array.from(table.children).forEach(section => { section.removeAttribute('role'); }) }

Stackblitz Example