我正在尝试读取组件列表,并在页面上动态创建它们。我正在为此使用ComponentResolver,并使用新的@ViewChild方式创建组件。
我有一个扩展ComponentCreator类的MainComponent文件。这个ComponentCreator类是一个基类,所有其他组件都可以"扩展"并使用它来创建各自的子组件。
以下是让事情变得更清楚的代码片段:
主组件.ts
export class MainComponent extends ComponentCreator {
@ViewChild("target", { read: ViewContainerRef }) target;
constructor(_componentResolver: ComponentResolver, metaService: MetaService) {
super(_componentResolver, metaService, "./src/app/meta.json", "MainComponent");
}
ComponentCreator.ts
export class ComponentCreator{
//declare variables
constructor(_componentResolver: ComponentResolver, _metaService: MetaService, _templateUrl: string, _templateName: string) {
this._componentResolver = _componentResolver;
this._templateUrl = _templateUrl;
this._metaService = _metaService;
this._templateName = _templateName;
}
ngAfterViewInit() {
//metaService gets the template. It's a json file in which all the child components of Main component are listed
this._metaService.getTemplate(this._templateUrl)
.subscribe(
_template => this._template = this.loadComponents(_template),
error => this._errorMessage = <any>error);
}
loadChildComponents(template) {
//Create components here
//'place' comes from the json file. It's Equal to target.
for(let component in jsonData)
this._componentResolver.resolveComponent(component).then((factory:ComponentFactory<any>)=> { this.cmpRef = this.place.createComponent(factory)});
}
}
我面临的问题是组件创建的顺序。例如,我有4个子组件,其中2个是纯HTML表,2个是使用d3绘制的一些图表。尽管我将创建顺序指定为1,2,3,4;渲染顺序混乱。当它们都加载在"target"div中时,HTML表会快速呈现,并位于两个图表之前。
有没有办法解决这个问题,或者我必须对表和图表使用单独的div,这样顺序就保持不变了?
我认为问题在于在for()
循环中调用异步代码,这会导致随机顺序。
使用Promise.all()
确保它们一个接一个地执行
Promise.all(
jsonData.map(component =>
this._componentResolver.resolveComponent(component)
.then((factory:ComponentFactory<any>)=> {
this.cmpRef = this.place.createComponent(factory);
});
)
);
另请参阅上的旧DynamicComponentLoader
的类似示例https://github.com/angular/angular/issues/7854#issuecomment-203988888