基于内容投影封装通用Clarity Datagrid报错问题求助
问题根因分析
你遇到的报错本质是两个核心问题导致的:
- 直接使用
<ng-content>投影时,clr-dg-column、clr-dg-row等Clr Datagrid子组件的依赖注入上下文是调用方组件,而非你自定义组件内部的<clr-datagrid>实例,因此会抛出找不到依赖、clr-dg-row只能在clr-datagrid内使用的错误。 - 直接继承
ClrDatagrid且模板中再次声明<clr-datagrid>的写法,会导致一个组件节点对应两个Datagrid实例,因此抛出NG0300多组件匹配错误;同时你引入的所有ɵ开头的服务都是Clarity的内部私有API,无版本兼容性保障,完全不建议使用。
可行解决方案
推荐使用模板出口(ngTemplateOutlet)方案,无需触碰Clarity内部逻辑,兼容性最强:
步骤1:修改自定义Datagrid组件代码
TS代码
import { Component, Input, TemplateRef } from '@angular/core'; @Component({ selector: 'app-custom-clr-datagrid', templateUrl: './custom-clr-datagrid.component.html', styleUrls: ['./custom-clr-datagrid.component.css'] }) export class CustomClrDatagridComponent<T = any> { // 接收外部传入的列模板 @Input() columnsTemplate: TemplateRef<void>; // 接收外部传入的行模板,上下文默认传入当前行数据 @Input() rowsTemplate: TemplateRef<{ $implicit: T }>; // 接收数据源 @Input() items: T[]; // 可自定义拓展其他配置:如每页条数、页码选项等 @Input() pageSize = 20; @Input() pageSizeOptions = [10, 20, 50, 100]; }
模板代码
<clr-datagrid class="datagrid-inner-height"> <!-- 渲染外部传入的列模板 --> <ng-container *ngTemplateOutlet="columnsTemplate"></ng-container> <!-- 渲染行 --> <clr-dg-row *clrDgItems="let item of items"> <ng-container *ngTemplateOutlet="rowsTemplate; context: {$implicit: item}"></ng-container> </clr-dg-row> <clr-dg-footer> <clr-dg-pagination #pagination [clrDgPageSize]="pageSize"> <clr-dg-page-size [clrPageSizeOptions]="pageSizeOptions">每页条数</clr-dg-page-size> {{pagination.firstItem + 1}} - {{pagination.lastItem + 1}} 条,共 {{pagination.totalItems}} 条 </clr-dg-pagination> </clr-dg-footer> </clr-datagrid>
步骤2:调用方使用方式
<app-custom-clr-datagrid [items]="users"> <!-- 传入列模板 --> <ng-template #columnsTemplate> <clr-dg-column>Col1</clr-dg-column> <clr-dg-column>Col2</clr-dg-column> </ng-template> <!-- 传入行模板,let-user接收上下文传入的当前行数据 --> <ng-template #rowsTemplate let-user> <clr-dg-cell>{{user.id}}</clr-dg-cell> <clr-dg-cell>{{user.name}}</clr-dg-cell> </ng-template> </app-custom-clr-datagrid>
如果需要完全兼容你最初的投影调用语法,可以采用依赖代理方案:在自定义组件的providers中将ClrDatagrid的依赖指向自定义组件内部通过@ViewChild获取的ClrDatagrid实例,再手动代理所有ClrDatagrid的公共属性和方法即可,无需继承ClrDatagrid类。
内容的提问来源于stack exchange,提问作者SMt
相关产品推荐
相关产品推荐

