ngx-datatable行详细信息内的动态组件


9

我正在使用ngx-datatable创建可重用的数据表,并且希望在行详细信息内呈现动态组件。数据表组件从父模块接收一个组件类作为参数,我使用ComponentFactory来创建组件。我可以看到该构造函数和onInit方法正在为动态组件运行,但没有附加到DOM。

这就是datatable html的row-detail的样子:

 <!-- [Row Detail Template] -->
        <ngx-datatable-row-detail rowHeight="100" #myDetailRow (toggle)="onDetailToggle($event)">
          <ng-template let-row="row" #dynamicPlaceholder let-expanded="expanded" ngx-datatable-row-detail-template>
          </ng-template>
        </ngx-datatable-row-detail>
 <!-- [/Row Detail Template] -->

这就是我的.ts文件的样子:

@ViewChild('myDetailRow', {static: true, read: ViewContainerRef}) myDetailRow: ViewContainerRef;
@ViewChild('dynamicPlaceholder', {static: true, read: ViewContainerRef}) dynamicPlaceholder: ViewContainerRef;

renderDynamicComponent(component) {
        var componentFactory = this.componentFactoryResolver.resolveComponentFactory(component);
        var hostViewConRef1 = this.myDetailRow;
        var hostViewConRef2 = this.dynamicPlaceholder;
        hostViewConRef1.createComponent(componentFactory);
        hostViewConRef2.createComponent(componentFactory);
}

另一点是,如果将我的#dynamicPlaceholderng-template放置在ngx-datatable之外,则它可以正常工作,并且呈现并显示动态模块。


1
这与内容投影有关。除非组件具有<ng-content>用于渲染任何嵌套标记的标签,否则不会渲染放置在组件标签之间的任何内容。
C_Ogoo

您能帮我举个快速的例子来帮助我吗?
Raghav Kanwal

Answers:


2

我们无法<ng-template>在运行时将组件呈现到Template()中,createComponent
因为afaik模板会在编译时由Angular处理。因此,我们需要一个在编译时有效的解决方案。


有缺点的解决方案

ng-content 可以在这里帮助我们:

<!-- [Row Detail Template] -->
<ngx-datatable-row-detail rowHeight="100" (toggle)="onDetailToggle($event)">
   <ng-template let-row="row" let-expanded="expanded" ngx-datatable-row-detail-template>
      <ng-content></ng-content>
   </ng-template>
</ngx-datatable-row-detail>
<!-- [/Row Detail Template] -->

然后,我们可以将所需的任何内容传递到详细信息视图:

<my-table>From the ouside but I cant access the current row :(</my-table>

但是有一个问题:ng-content当我们要访问传递的模板中的当前行时,我们将无法使用。


但是ngx-datatable让我们蒙上了一层阴影。我们可以将模板传递给ngx-datatable-row-detail指令:

<ngx-datatable-row-detail [template]="myDetailTemplate "rowHeight="100" (toggle)="onDetailToggle($event)">
</ngx-datatable-row-detail>

然后可以通过@Input变量将模板从外部的任何组件传递到:

<ng-template #myDetailTemplate let-row="row">
  From the outside with access to the current row: {{row.name}}
</ng-template>

看一下stackblitz,我在其中编写了一个my-tablepoc组件。


0

定义一个将其内容公开为的组件 TemplateRef

<ng-template #myTemplate let-row="row" let-expanded="expanded" ngx-datatable-row-detail-template>

    <div><strong>Address</strong></div>
    <div>{{ row?.address?.city }}, {{ row?.address?.state }}</div>
</ng-template>

使用ViewChild作出访问属性TemplateRef

export class DynamicComponent implements OnInit {

  @ViewChild("myTemplate",{static:true}) myTempalte : TemplateRef<any>
...
}

定义没有模板的行详细信息

<ngx-datatable-row-detail rowHeight="100" (toggle)="onDetailToggle($event)">
</ngx-datatable-row-detail>

定义属性以访问指令

@ViewChild(DatatableRowDetailDirective,{static:true}) templ:DatatableRowDetailDirective; 
 constructor(  
    private cfr: ComponentFactoryResolver, //import cfr
  )
....
toggleExpandRow(row) { 
   const factory = this.cfr.resolveComponentFactory<DynamicComponent>(
      DynamicComponent
    );

    const component = factory.create(this.injector,[]);   //create component dynamically
    this.templ._templateInput = component.instance.myTempalte; // set directives template to your components template 
    this.table.rowDetail.toggleExpandRow(row);
}

Stackblitz

编辑: 我弄弄了它的ngx-datatable源可悲的部分ngx-datatable-row-detail不是组件而是指令,并且它没有附加到DOM。因此,它没有ViewContainer参考。这使得向其中注入元素有些困难。您可以做的是在组件中定义模板,并使用TemplateRefs并将其分配给呈现组件的位置。


感谢您的输入,我尝试采用您的方法,但el.setAttribute is not a function在componentFactory.create方法上遇到错误。知道为什么会这样吗?this.dynamicPlaceholder.elementRef.nativeElement返回评论,可以吗?
Raghav Kanwal

@RaghavKanwal看到我的最新答案。
埃尔达
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.