Thành phần động bên trong chi tiết hàng ngx-datable


9

Tôi đang tạo một dữ liệu có thể sử dụng lại bằng cách sử dụng ngx-datable và tôi muốn có các thành phần động được hiển thị bên trong chi tiết hàng. Thành phần có thể truy cập nhận được một lớp thành phần dưới dạng đối số từ mô đun mẹ và tôi sử dụng ElementFactory để tạoComponent. Tôi có thể thấy rằng hàm tạo và các phương thức onInit đang chạy cho thành phần động nhưng nó không được gắn vào DOM.

Đây là những gì html có thể truy xuất được cho chi tiết hàng:

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

Và đây là tệp .ts của tôi trông như thế nào:

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

Một điểm khác là nếu #dynamicPlaceholdermẫu ng của tôi được đặt bên ngoài ngx-datable, nó hoạt động và mô-đun động được hiển thị và hiển thị.


1
Điều này là để làm với nội dung chiếu. Bất cứ điều gì được đặt giữa các thẻ thành phần, sẽ không được hiển thị trừ khi thành phần đó có <ng-content>thẻ để hiển thị bất kỳ đánh dấu lồng nhau nào.
C_Ogoo

Bạn có thể vui lòng giúp tôi với một ví dụ nhanh để giúp đỡ trong trường hợp của tôi?
Raghav Kanwal

Câu trả lời:


2

Chúng tôi không thể kết xuất một thành phần thành Mẫu ( <ng-template>) trong thời gian chạy với createComponent
vì các mẫu afaik được Angular xử lý tại thời gian biên dịch. Vì vậy, chúng ta cần một giải pháp hoạt động vào thời gian biên dịch.


Giải pháp với nhược điểm

ng-content có thể giúp chúng tôi ở đây:

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

Sau đó chúng ta có thể chuyển bất cứ thứ gì chúng ta muốn vào chế độ xem chi tiết:

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

Nhưng có một vấn đề: Chúng tôi không thể sử dụng ng-contentkhi chúng tôi muốn truy cập vào hàng hiện tại trong mẫu đã qua.


Giải pháp

Nhưng ngx-datatablecó chúng tôi bảo hiểm. Chúng ta có thể truyền một mẫu cho lệnh ngx-datatable-row-detail:

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

Mẫu sau đó có thể được truyền vào từ bất kỳ thành phần nào ở bên ngoài thông qua một @Inputbiến:

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

Hãy nhìn vào stackblitz , nơi tôi đã viết một my-tablethành phần là poc.


0

Xác định một thành phần hiển thị nội dung của nó là 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>

Sử dụng ViewChildđể tạo một tài sản có thể truy cập choTemplateRef

export class DynamicComponent implements OnInit {

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

Xác định chi tiết hàng của bạn mà không có mẫu

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

Xác định một tài sản để truy cập vào chỉ thị

@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

Chỉnh sửa: Tôi loay hoay với ngx-datatablephần buồn nguồn của nó ngx-datatable-row-detailkhông phải là một thành phần mà là chỉ thị và nó không được đính kèm với DOM. Vì vậy, nó không có ViewContainerref. Điều này làm cho việc tiêm các yếu tố vào nó hơi khó khăn một chút. Những gì bạn có thể làm là xác định các mẫu trong thành phần của bạn và sử dụng TemplateRefs và gán chúng ở nơi bạn kết xuất thành phần của mình.


Cảm ơn về đầu vào, tôi đã thử áp dụng phương pháp của bạn nhưng tôi gặp el.setAttribute is not a functionlỗi về phương thức componentFactory.create. Bất cứ ý tưởng tại sao điều đó có thể xảy ra? this .dynamicPlaceholder.elementRef.nativeEuity trả về một bình luận, có thể vậy không?
Raghav Kanwal

@RaghavKanwal xem câu trả lời cập nhật của tôi.
Eldar
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.