Подтвердить что ты не робот

Angular2 загрузка динамического содержимого /html в цикл for

У меня есть json-массив, который может содержать либо компонент, либо селектор html для компонента, который я хочу загрузить. Я пытаюсь загрузить эти данные в цикл 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>
4b9b3361

Ответ 1

Я также искал способ сделать это. Я увидел ответ @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;
  }
}

Ответ 2

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