Component แบบไดนามิกภายใน ngx-datatable-detail-row


9

ฉันกำลังสร้าง datatable ที่สามารถใช้ซ้ำได้โดยใช้ ngx-datatable และฉันต้องการให้ส่วนประกอบแบบไดนามิกแสดงผลภายในรายละเอียดแถว องค์ประกอบ DataTable ได้รับชั้นองค์ประกอบเป็นอาร์กิวเมนต์จากโมดูลหลักและฉันใช้ ComponentFactory เพื่อ createComponent ฉันเห็นว่าตัวสร้างและเมธอด onInit กำลังรันสำหรับคอมโพเนนต์แบบไดนามิก แต่ไม่ได้ถูกแนบกับ DOM

นี่คือสิ่งที่ HTML DataTable ดูเหมือนว่าสำหรับรายละเอียดแถว:

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

เราไม่สามารถแสดงองค์ประกอบเป็นเทมเพลต ( <ng-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-tableส่วนประกอบเป็น poc


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.