10

我有一个 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>
4

2 回答 2

9

我也在寻找一种方法来做到这一点。我看到了@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;
  }
}

于 2016-05-22T22:09:04.840 回答
3

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

于 2016-02-19T01:57:37.653 回答