ngx-datatable row-detail内の動的コンポーネント


9

ngx-datatableを使用して再利用可能なデータテーブルを作成しています。動的コンポーネントを行の詳細の内部にレンダリングしたいと思います。データテーブルコンポーネントは、親モジュールから引数としてコンポーネントクラスを受け取り、ComponentFactoryを使用してcreateComponentを作成します。動的コンポーネントに対してコンストラクターとonInitメソッドが実行されていることがわかりますが、DOMに接続されていません。

これは、row-detailのデータテーブルhtmlのようになります。

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

回答:


2

afaikテンプレートはコンパイル時にAngularによって処理されるため<ng-template>、実行時にコンポーネントをテンプレート()にレンダリングすることはできませんcreateComponent
。したがって、コンパイル時に機能するソリューションが必要です。


欠点のあるソリューション

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>

私がコンポーネントをpocとして記述したstackblitzをmy-tableてください。


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私の更新された答えを見てください。
Eldar
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.