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

У меня есть массив json, который может содержать либо компонент, либо селектор html для компонента, который я хочу загрузить. Я пытаюсь загрузить эти данные внутри цикла for. Когда я пытаюсь интерполировать значение {{d.html}}, оно отображается как текст плана. Когда я использую подход innerHTML ниже и проверяю дом, я вижу там html, но он не ведет себя как пользовательский компонент (дом будет просто содержать вместо его инициализации и замены его шаблоном компонентов.

Я посмотрел на загрузчик динамического контента, но он не подходит. Это в цикле for и поэтому не может использовать синтаксис шаблона, поэтому loadIntoLocation не будет работать для меня. Также не уверен, как это будет работать, если компонент будет иметь какие-либо входные данные.

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

person Chris    schedule 17.02.2016    source источник


Ответы (2)


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

person Henrique Rotava    schedule 22.05.2016
comment
Я думаю, что этот фрагмент должен войти в документы angular. Раньше я визуализировал встроенный компонент в шаблоне, полученном с сервера, и он работал отлично. Большое спасибо. - person Tom Makin; 24.07.2016
comment
Это должен быть официальный ответ - person dopatraman; 30.07.2016
comment
ComponentResolver устарел. Не могли бы вы обновить? Спасибо - person x0a; 30.09.2016

Шаблон динамического рендеринга 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

person guyoung    schedule 19.02.2016