ngx-datatable row-detail 내의 동적 구성 요소


9

ngx-datatable을 사용하여 재사용 가능한 데이터 테이블을 만들고 있으며 행 세부 정보 안에 동적 구성 요소를 렌더링하고 싶습니다. 데이터 테이블 구성 요소는 부모 모듈에서 인수로 구성 요소 클래스를 받고 ComponentFactory를 사용하여 구성 요소를 만듭니다. 생성자와 onInit 메소드가 동적 구성 요소에 대해 실행되고 있지만 DOM에 첨부되지 않았 음을 알 수 있습니다.

이것은 행 세부 사항에 대한 datatable 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>런타임에 구성 요소를 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>

상기 살펴보세요 stackblitz 내가 쓴, my-tablePOC로 구성 요소를.


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

스택 블리츠

편집 : 나는 함께 바이올린 ngx-datatable이의 소스 슬픈 일부 ngx-datatable-row-detail구성 요소 만 지시하지 않으며이 DOM에 연결되어 있지 않습니다. 따라서 ViewContainer심판 이 없습니다 . 이것은 요소를 주입하는 것을 조금 어렵게 만듭니다. 할 수있는 일은 컴포넌트에서 템플릿을 정의하고을 사용 TemplateRef하여 컴포넌트를 렌더링 할 위치에 할당하는 것입니다.


입력 주셔서 감사합니다, 나는 당신의 방법을 채택하려고 시도했지만 el.setAttribute is not a functioncomponentFactory.create 메소드에 오류 가 발생했습니다. 왜 그런 일이 일어날 지 아십니까? this.dynamicPlaceholder.elementRef.nativeElement는 주석을 반환합니다.
Raghav Kanwal

@RaghavKanwal 업데이트 된 답변을 참조하십시오.
Eldar
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.