我构建了一个数据表组件,其中使用结构指令来传递 rowTemplate:
<bs-datatable [data]="artists">
<tr *bsRowTemplate="let artist">
<td class="text-nowrap">{{ artist.name }}</td>
<td class="text-nowrap">{{ artist.yearStarted }}</td>
<td class="text-nowrap">{{ artist.yearQuit }}</td>
</tr>
</bs-datatable>
我试图在自定义结构指令中提供类型推断,因此结构指令的通用类型应该从父组件推断出来。 根据文档,您应该能够简单地实现一个
ngTemplateContextGuard
:
@Component({ ... })
export class DatatableComponent<TData> {
@Input() data: TData[] = [];
}
@Directive({ selector: '[appDatatableRow]' })
export class DatatableRowDirective<TData> {
constructor(public datatable: DatatableComponent<TData>, public template: TemplateRef<TData>) { }
static ngTemplateContextGuard<TData>(dir: DatatableRowDirective<TData>, ctx: unknown)
: ctx is DatatableRowContext<TData> {
return true;
}
}
组件上的类型推断按预期工作:
但是我无法获得结构指令来推断这个泛型类型:
目标显然是在 VS Code 中推断出
$implicit
变量:
为什么这没有像我预期的那样工作?我还缺少什么?我希望结构指令能够推断父数据表的通用类型。
InstanceOf
- Let
- Select2
(类似问题)类似文章/讨论:
我最终使用了结构指令的
of
表示法:
@Directive({ selector: '[bsRowTemplate]' })
export class BsRowTemplateDirective<TData> {
constructor(private datatableComponent: BsDatatableComponent<TData>, templateRef: TemplateRef<BsRowTemplateContext<TData>>) {
this.datatableComponent.rowTemplate = templateRef;
}
@Input() set bsRowTemplateOf(value: PaginationResponse<TData> | undefined) {
this.datatableComponent.data = value;
}
public static ngTemplateContextGuard<TData>(
dir: BsRowTemplateDirective<TData>,
ctx: any
): ctx is BsRowTemplateContext<Exclude<TData, false | 0 | '' | null | undefined>> {
return true;
}
}
export class BsRowTemplateContext<TData = unknown> {
public $implicit: TData = null!;
}
数据表
@Component({
selector: 'bs-datatable',
...
})
export class BsDatatableComponent<TData> {
...
rowTemplate?: TemplateRef<BsRowTemplateContext<TData>>;
data?: PaginationResponse<TData>;
}
使用方法
<bs-datatable #tabel [(settings)]="settings" (settingsChange)="loadArtists()">
<div *bsDatatableColumn="'Name'; sortable: true">
1. Artist
</div>
<div *bsDatatableColumn="'YearStarted'; sortable: true">
2. Year started
</div>
<div *bsDatatableColumn="'YearQuit'; sortable: true">
3. Year quit
</div>
<tr *bsRowTemplate="let artist of artists">
<td class="text-nowrap">{{ artist.name }}</td>
<td class="text-nowrap">{{ artist.yearStarted }}</td>
<td class="text-nowrap">{{ artist.yearQuit }}</td>
</tr>
</bs-datatable>