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);
}
別のポイントは、もし私の#dynamicPlaceholder
ng-templateはngx-datatableの外側に配置され、機能し、動的モジュールがレンダリングおよび表示されます。
createComponent
を使用して、実行時にコンポーネントをテンプレート(<ng-template>
)にレンダリングすることはできません。
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
が対象となりました。テンプレートをthengx-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-table
コンポーネントをpocとして記述しました。
コンテンツを
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);
}
編集:ngx-datatable
ソース悲しい部分ngx-datatable-row-detail
はコンポーネントではなくディレクティブであり、DOMにアタッチされていません。したがって、ViewContainer
参照はありません。これはそれに要素を注入することを少し難しくします。コンポーネントでテンプレートを定義し、TemplateRef
sを使用して、コンポーネントをレンダリングする場所にテンプレートを割り当てることができます。