如何在按代码创建组件实例时动态设置templateUrl?

时间:2017-05-05 08:39:19

标签: angular angular2-directives angular2-components

我正在考虑在Angular中创建一个小组件来完成<ng-include>在angularJS中所做的事情。

首先,我必须给组件一个模板或templateUrl进行编译?如果它只是在运行时才知道怎么办?

@Component({
  selector: 'my-template',
  // templateUrl: '',    //won't render, must give it something?
})
export class MyTemplate {

 @Input() templateURL: string;

  constructor() {
    console.log("template component was created!");
  }

}

我想在代码中创建该组件的实例并给出其templateUrl。这样的事情:

 var factory = this.resolver.resolveComponentFactory(MyTemplate);
factory.templateUrl =    // Is that possible?

能以某种方式完成吗? templateUrl将来自@input 如何在代码中创建组件的实例并给它输入?

1 个答案:

答案 0 :(得分:0)

我认为你应该使用动态组件加载来做到这一点。

我们可能会创建 HtmlOutlet 指令,该指令将使用所需的 templateUrl 创建动态组件:

@Directive({
  selector: 'html-outlet' 
})
export class HtmlOutlet {
  @Input() html: string;

  constructor(private vcRef: ViewContainerRef, private compiler: Compiler) {}

  ngOnChanges() {
    const html = this.html;
    if (!html) return;

    @Component({
      selector: 'dynamic-comp',
      templateUrl: html
    })
    class DynamicHtmlComponent  { };

    @NgModule({
      imports: [CommonModule],
      declarations: [DynamicHtmlComponent]
    })
    class DynamicHtmlModule {}

    this.compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule)
      .then(factory => {
        const compFactory = factory.componentFactories
               .find(x => x.componentType === DynamicHtmlComponent);
        const cmpRef = this.vcRef.createComponent(compFactory, 0);
        cmpRef.instance.prop = 'test';
        cmpRef.instance.outputChange.subscribe(()=>...);
    });
  }
}

然后使用它:

<html-outlet [html]="article?.html">

html article.html

的路径