Angular 2 中的组件创建顺序

Component creation order in Angular 2

我正在尝试读取组件列表并在我的页面上动态创建它们。我正在为此使用 ComponentResolver 并使用新的 @ViewChild 方式创建组件。

我有一个扩展 ComponentCreator 的 MainComponent 文件 class。此 ComponentCreator class 是一个基础 class,所有其他组件都可以 'extend' 并使用它来创建各自的子组件。

以下是使事情更清楚的代码片段:

MainComponent.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);
     });
  )
);

另请参阅 https://github.com/angular/angular/issues/7854#issuecomment-203988888

中旧 DynamicComponentLoader 的类似示例