web-dev-qa-db-ja.com

Angular2がforループで動的コンテンツ/ htmlを読み込む

ロードするコンポーネントのコンポーネントまたはhtmlセレクターのいずれかを含むことができるjson配列があります。このデータをforループ内にロードしようとしています。値{{d.html}}を補間しようとすると、プランテキストとして表示されます。以下のinnerHTMLアプローチを使用してdomを検査すると、そこにhtmlが表示されますが、カスタムコンポーネントとして動作しません(domは、初期化してコンポーネントテンプレートで置き換えるのではなく、単に含むだけです)。

動的コンテンツローダーを確認しましたが、うまくいかないようです。これはforループ内にあるため、テンプレート構文を使用できないため、loadIntoLocationは機能しません。また、コンポーネントに入力があった場合の動作もわかりません。

<div *ngFor="#d of dtabs" class="tab-pane" id="tab-{{d.component}}">
  <div [innerHTML]="d.html"></div>
</div>
10
Chris

それを行う方法も探していました。 @guyoungの答えを見て、それに基づいて何かを構築しました。しかし、その後、私はDynamicComponentLoader.loadIntoLocation()が最後のバージョンではもう存在しないこと、およびDynamicComponentLoaderがすでに非推奨になっていることに気付きました。

私はいくつかのドキュメントと投稿を読み、うまく機能する新しいディレクティブを作成しました。チェックアウト:

import {
  Component,
  ComponentResolver,
  Directive,
  ViewContainerRef,
  Input,
  Injector,
  ApplicationRef
} from "@angular/core";

/**

  This component render an HTML code with inner directives on it.
  The @Input innerContent receives an array argument, the first array element
  is the code to be parsed. The second index is an array of Components that
  contains the directives present in the code.

  Example:

  <div [innerContent]="[
    'Go to <a [routerLink]="[Home]">Home page</a>',
    [RouterLink]
  ]">

**/
@Directive({
  selector: '[innerContent]'
})
export class InnerContent {

  @Input()
  set innerContent(content){
    this.renderTemplate(
      content[0],
      content[1]
    )
  }

  constructor(
    private elementRef: ViewContainerRef,
    private injector: Injector,
    private app: ApplicationRef,
    private resolver:ComponentResolver){
  }

  public renderTemplate(template, directives) {
    let dynComponent = this.toComponent(template, directives)
    this.resolver.resolveComponent(
      dynComponent
    ).then(factory => {
      let component = factory.create(
        this.injector, null, this.elementRef._element.nativeElement
      );

      (<any>this.app)._loadComponent(component);
      component.onDestroy(() => {
        (<any>this.app)._unloadComponent(component);
      });
      return component;
    });
  }

private toComponent(template, directives = []) {
  @Component({
    selector: 'gen-node',
    template: template,
    directives: directives
  })
  class DynComponent {}
    return DynComponent;
  }
}
9
Henrique Rotava

Angular2動的にテンプレートをレンダリング

import { Component, View, DynamicComponentLoader, ElementRef} from 'angular2/core';
import {bootstrap}    from 'angular2/platform/browser'
@Component({
    selector: 'some-component',
    properties: ['greeting'],
    template: `
    <b>{{ greeting }}</b>
  `
})
class SomeComponent { }
@Component({
    selector: 'app'
})
@View({
    template: `
    <h1>Before container</h1>
    <div #container></div>
    <h2>After container</h2>
  `
})
class App {
    loader: DynamicComponentLoader;
    elementRef: ElementRef;

    constructor(loader: DynamicComponentLoader, elementRef: ElementRef) {
        this.laoder = loader;
        this.elementRef = elementRef;

        // Some async action (maybe ajax response with html in it)
        setTimeout(() => this.renderTemplate(`
      <div>
    <h2>Hello</h2>
    <some-component greeting="Oh, hey"></some-component>
      </div>
    `, [SomeComponent]), 1000);
    }

    renderTemplate(template, directives) {
        this.laoder.loadIntoLocation(
            toComponent(template, directives),
            this.elementRef,
            'container'
        )
    }
}
function toComponent(template, directives = []) {
    @Component({ selector: 'fake-component' })
    @View({ template, directives })
    class FakeComponent { }

    return FakeComponent;
}


bootstrap(App);

完全なコード: https://github.com/guyoung/GyPractice-Angular2Advanced/tree/master/apps/dynamically_render_template

3
guyoung