【发布时间】:2018-03-05 15:29:00
【问题描述】:
我正在尝试将动态模板加载到 Angular 5 应用程序中。 首先尝试的是 Angular 文档中的示例,https://angular.io/guide/dynamic-component-loader 这是一个死胡同,因为它所做的只是动态加载静态组件。
其次是来自 AngularInDepth.com Max NgWizard K 的消息灵通的博客文章 https://blog.angularindepth.com/here-is-what-you-need-to-know-about-dynamic-components-in-angular-ac1e96167f9e
这就像动态渲染模板的魅力。但是,我在尝试连接动态组件以进行递归调用甚至加载通用模块时遇到了麻烦。
环顾 stackoverflow,大多数答案都已过时,因为 plunkers 无法正常工作,而少数有效的答案并不能真正解决循环依赖问题,甚至除了在我的情况下已经工作的插值之外加载模块。
我已经创建了一个 Angular 文档项目来演示这个问题 https://stackblitz.com/edit/angular-aa3ah1?file=src%2Fapp%2Fheroes%2Fheroes.component.ts
import { Component, OnInit, Input, ViewChild, Compiler, NgModule } from '@angular/core';
import { ViewContainerRef } from '@angular/core';
import { Portal } from './portal'
import { SharedModule } from './shared.module'
@Component({
selector: 'app-heroes',
templateUrl: './heroes.component.html',
styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit {
@Input() msg: any;
@ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef;
templates = [//interpolation works without a problem
`<span>
This works: {{msg.comment}}
</span>`,
// How to import a directive in the template?
`<span *ngFor="let comment of msg.childComments">
Directive : {{comment.comment}}
</span>`,
// How to reuse the portal without circular dependancies???
`<span>
This does not work because app-heroes
is not accessible and importing module causes circular dependancies
{{msg.comment}}
</span>
<span *ngFor="let comment of msg.childComments">
<app-heroes [msg]="comment"></app-heroes>
</span>
`];
constructor(private _compiler: Compiler) { }
ngOnInit() {
this.loadTemplate(this.templates[0], this.msg, this.vc, this._compiler);
}
loadTemplate(myTemplate: string, data: any, vc: ViewContainerRef, compiler: Compiler){
const portal = Component({template: myTemplate})(Portal);
//const pModule = NgModule({declarations: [portal], imports: [HeroesComponent]})(class{});
const pModule = NgModule({declarations: [portal], imports: [SharedModule]})(class{});
compiler.compileModuleAndAllComponentsAsync(pModule)
.then((factories) => {
const f = factories.componentFactories[0];
const cmpRef = vc.createComponent(f);
cmpRef.instance.msg = data;
});
}
}
- 如何让常用模块在我的动态组件(模板[1])中工作?
- 如何重用动态组件来制作递归指令(模板[2])?
【问题讨论】: