Поскольку я не мог найти реально работающее решение, я написал свой «быстрый и грязный» код для фиксированного заголовка.Тем не менее я надеюсь найти гораздо лучший путь в будущем.Возможно, в следующем выпуске Cdk будет предложено решение.
Что я сделал сейчас, так это написал (более или менее хакерскую) директиву, которая клонирует таблицу из cdk-virtual-scroll-viewport
и размещает клонированный узел раньше.На следующем шаге visibility
элемента table thead
устанавливается на collapse
.
Использование:
<cdk-virtual-scroll-viewport [itemSize]="30" cloneThead>
<table class="table table-hover">
<thead>
...
</thead>
<tbody>
<tr *cdkVirtualFor="let item of list">
<td>...</td>
...
</tr>
</tbody>
</table>
</cdk-virtual-scroll-viewport>
Директива cloneThead
имеет виддовольно просто:
import { Directive, AfterViewInit, ElementRef } from '@angular/core';
@Directive({
selector: '[cloneThead]'
})
export class CloneDirective implements AfterViewInit{
constructor(private el: ElementRef) {}
ngAfterViewInit(){
let cloned = this.el.nativeElement.cloneNode(true);
let table = cloned.querySelector("table");
table.style.position = 'sticky';
table.style.top = '0';
table.style.zIndex = '100';
this.el.nativeElement.appendChild(table);
}
}
Это работает довольно хорошо, но имеет еще одну большую проблему: клон создается после ngAfterViewInit
, что приводит к тому, что строки таблицы cdkVirtualFor
еще не созданы для DOM.
Это хорошо для самого клона, потому что он еще не содержит tr
элементов tbody
, НО вычисленные стили CSS для правильной ширины для th
элементов также неизвестен.
Таким образом, все th
элементы должны иметь атрибут CSS width.В противном случае ширина th
и ширина td
могут различаться - что выглядит ужасно ...
Может быть, у кого-то еще есть решение сделать "настоящий" клон после того, как нарисована таблица cdk-virtual-scroll-viewport
.