2017-02-16 2 views
4

구성 된 요소를로드하는 "대시 보드"가 있습니다. 비표준 요소를 소독 얻을 때문에 ngFor에서 동적으로 구성 요소를 추가합니다.

<div class="dash-container" [ngGrid]="gridConfig"> 
    <div *ngFor="let box of boxes; let i = index" 
     [(ngGridItem)]="box.config" 
     (onItemChange)="updateItem(i, $event)" 
     (onResize)="onResize(i, $event)" 
     (onDrag)="onDrag(i, $event)" 
     (onDragStop)="onDragStop(i,$event)" 
     [ngClass]="box.class" 
    > 
     <div class="handle"><h4>{{box.title}}</h4></div> 
     <div [innerHTML]= "box.content"></div> 
    </div> 
    </div> 

지금 <div [innerHTML]= "box.content"></div>가 작동하지 않습니다 대시 보드 템플릿이 있습니다. 최신 각도 2.4.6 (RC 6) 실행.

내가 동적 구성 요소에 대해 찾을 수있는 예제를 살펴 봅니다.하지만 모든 구성 요소는 현재 구성 요소에 구성 요소를 추가하기 만합니다. 그러나 위 예제에서와 같이 특정 div에 필요합니다.

은 종종 @ViewChild과 함께 사용됩니다. 하지만 난 그냥 루프 내에서이 작업을 수행 할 수 없습니다

ngAfterViewInit() { 
    const dashWidgetsConf = this.widgetConfigs(); 
    for (var i = 0; i < dashWidgetsConf.length; i++) { 
     const conf = dashWidgetsConf[i]; 

     @ViewChild(conf.id, {read: ViewContainerRef}) var widgetTarget: ViewContainerRef; 

     var widgetComponent = this.componentFactoryResolver.resolveComponentFactory(UnitsComponent); 
     widgetTarget.createComponent(widgetComponent); 
    } 
    } 

@viewchild은 '장식이 여기에 유효하지 않은'제공합니다. 내 구성 요소에서 conf 목록 (구성 요소)에있는 구성 요소를로드하고 특정 div (divs는 #{{conf.id}}) 안에 추가 할 수 있습니까?

+1

http://stackoverflow.com/questions/36325212/angular-2-dynamic-tabs-with-user-click-chosen-components/36325468#36325468과 매우 유사하게 보이며 http :// /stackoverflow.com/questions/34784778/equivalent-of-compile-in-angular-2/37044960#37044960 –

+1

그러나 이러한 예제에서 "대상"은 고정되어 있습니다. 즉, 처음부터 @ViewChild로 정의 된 이미 알려진 요소입니다. 나는 그것들을 id와 함께 x 개의 요소에 추가 할 필요가있다. 나는 템플릿에서 미리 정의 할 수 없다. – Agony

+0

런타임시 생성되는 구성 요소의 템플리트에있는 모든 것을 미리 정의 할 수 있습니다. 즉, 동적으로 추가 할뿐만 아니라 런타임에 전체 구성 요소가 작성된다는 의미입니다. –

답변

8

몇 가지 연구가 끝난 후 이것이 해결책이되었습니다 (4.0.0에서 작동 함).

로드 ID로 모든 ViewContainerRef 대상 :

@ViewChildren('dynamic', {read: ViewContainerRef}) public widgetTargets: QueryList<ViewContainerRef>; 

그런 다음 루프는 그 대상을 얻을 이상, 구성 요소의 공장을 만들고 createComponent를 호출합니다.
또한 구성 요소 참조를 사용하여 다른 구성 요소 등록을 구독하거나 설정할 수 있습니다.

<div *ngFor="let box of boxes; let i = index" > 
    <ng-template #dynamic></ng-template> 
</div> 

그리고 목표의 순서 : 제목 같은 구성 요소 ID 등 템플릿에서 다음

- widgetComponents

ngAfterViewInit() { 
    const dashWidgetsConf = this.widgetConfigs(); 
    const widgetComponents = this.widgetComponents(); 
    for (let i = 0; i < this.widgetTargets.toArray().length; i++) { 
     let conf = dashWidgetsConf[i]; 
     let component = widgetComponents[conf.id]; 
     if(component) { 
      let target = this.widgetTargets.toArray()[i]; 
      let widgetComponent = this.componentFactoryResolver.resolveComponentFactory(component); 
      let cmpRef: any = target.createComponent(widgetComponent); 

      if (cmpRef.instance.hasOwnProperty('title')) { 
       cmpRef.instance.title = conf.title; 
      } 
     } 
    } 
} 

은 내가 특정 구성 요소 정보를 저장 {key: component}widgetConfigs는 객체이다 내 conf와 동일합니다 (boxes이 생성됩니다) - 그래서 나는 그들을 순서대로 사용할 수 있고 올바른 conf와 구성 요소를 얻기 위해 색인으로 사용할 수 있습니다.

+0

우수. 감사합니다. –

+0

@Agony 앞으로 '상자'의 가치가 바뀌면 어떻게 될까요? 예. 새 상자가 기존 상자에 추가됩니다. 동적으로로드 된 구성 요소의 경우 DOM이 새 상자로 업데이트되지 않는다는 것을 알 수있었습니다. – Tejas

관련 문제