ngFor でコンポーネントを動的に追加する質問する

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>動作しません。最新の Angular 2.4.6 (RC 6) を実行しています。

動的コンポーネントの例をいくつか見てみたのですが、現在のコンポーネントにコンポーネントを追加するだけであることがわかりました。ただし、上記の例のように、非常に特定の div にそれらが必要です。

ComponentFactoryResolverは と一緒に使用されることが多いです@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 リスト (ループ内) からコンポーネントをロードし、#{{conf.id}}コンポーネント内の特定の div (divs got ) 内に追加するにはどうすればよいですか?

ベストアンサー1

いくつか調査した後、これが私が思いついた解決策です (Angular 4.0.0 で動作します)。

ViewContainerRefID ですべてのターゲットをロードします。

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

次に、それらをループしてターゲットを取得し、コンポーネントのファクトリを作成して を呼び出しますcreateComponent
また、コンポーネント参照を使用して、他のコンポーネント プロパティをサブスクライブまたは設定することもできます。

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

widgetComponentsオブジェクトであり{key: component}widgetConfigsタイトル、コンポーネント ID などの特定のコンポーネント情報を保存する場所です。

次にテンプレートで:

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

また、ターゲットの順序は conf と同じです (boxesそこから生成されます)。そのため、順番にループし、i をインデックスとして使用して、正しい conf とコンポーネントを取得できます。

おすすめ記事