Ngx-datatable satır detayında Dinamik Bileşen


9

Ben ngx-datatable kullanarak yeniden kullanılabilir bir datatable oluşturma ve satır detay içinde render dinamik bileşenler istiyorum. Datatable bileşeni, bir üst modülünden bağımsız değişken olarak bir bileşen sınıfı alır ve benComcomponent oluşturmak için ComponentFactory kullanın. Dinamik bileşen için yapıcı ve onInit yöntemlerinin çalıştığını, ancak DOM bağlı olmadığını görebilirsiniz.

Datatable html, satır ayrıntısı için şöyle görünür:

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

Ve işte .ts dosyam şöyle görünüyor:

@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);
}

Başka bir nokta, eğer #dynamicPlaceholderng-şablonum ngx-datatable'ın dışına yerleştirilirse, çalışır ve dinamik modülün oluşturulması ve görüntülenmesidir.


1
Bu, içerik projeksiyonu ile ilgilidir. Bileşen etiketi arasına yerleştirilen hiçbir şey, bileşen <ng-content>iç içe işaretleme yapmak için bir etikete sahip olmadığı sürece oluşturulmaz.
C_Ogoo

Davamda yardımcı olacak kısa bir örnek için lütfen bana yardımcı olur musunuz?
Raghav Kanwal

Yanıtlar:


2

Afaik şablonları derleme zamanında Angular tarafından işlendiğinden, bir bileşeni <ng-template>çalışma zamanında Şablon ( ) haline getiremeyiz createComponent
. Derleme zamanında çalışan bir çözüme ihtiyacımız var.


Sakıncaları olan çözüm

ng-content burada bize yardımcı olabilir:

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

Daha sonra istediğimiz her şeyi ayrıntı görünümüne aktarabiliriz:

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

Ancak bir sorun var:ng-content Geçirilen şablondaki geçerli satıra erişmek istediğimizde kullanamıyoruz .


Çözüm

Ama ngx-datatablebizi örtbas etti. ngx-datatable-row-detailDirektife bir şablon aktarabiliriz :

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

Şablon daha sonra bir @Inputdeğişken aracılığıyla dışarıdaki herhangi bir bileşenden aktarılabilir :

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

Bir bileşeni poc olarak yazdığım stackblitz'e bir göz atın my-table.


0

İçeriğini gösteren bir bileşeni tanımlayın 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>

İçin ViewChilderişilebilir bir mülk oluşturmak için kullanınTemplateRef

export class DynamicComponent implements OnInit {

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

Şablon olmadan satır detayınızı tanımlayın

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

Direktife erişmek için bir mülk tanımlayın

@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

Düzenleme: Ben fiddled ngx-datatableo kaynağının üzücü kısmı ngx-datatable-row-detail, bir bileşen ama direktif değildir ve DOM bağlı değil. Yani ViewContainerref yok . Bu, içine enjekte edici elemanları biraz zorlaştırır. Yapabileceğiniz şey, bileşeninizdeki şablonları tanımlamak ve TemplateRefs kullanmak ve bunları bileşeninizi oluşturduğunuz yere atamaktır.


Giriş için teşekkürler, yönteminizi benimsemeyi denedim ama el.setAttribute is not a functioncomponentFactory.create yönteminde hata alıyorum . Bunun neden olabileceği hakkında bir fikrin var mı? this.dynamicPlaceholder.elementRef.nativeElement bir yorum döndürür, değil mi?
Raghav Kanwal

@RaghavKanwal güncellenmiş cevabımı gör.
Eldar
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.