1

コンポーネントのリストを読み込んで、自分のページに動的に作成しようとしています。これには ComponentResolver を使用し、新しい @ViewChild 方法を使用してコンポーネントを作成しています。

ComponentCreator クラスを拡張する MainComponent ファイルがあります。この ComponentCreator クラスは、他のすべてのコンポーネントが「拡張」して、それぞれの子コンポーネントを作成するために使用できる基本クラスです。

わかりやすくするためのコード スニペットを次に示します。

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 と指定していますが、レンダリングの順序がめちゃくちゃです。それらはすべて「ターゲット」div 内にロードされるため、HTML テーブルは高速にレンダリングされ、両方のチャートの前に表示されます。

それを修正する方法はありますか、または順序が同じになるようにテーブルとチャートに別々の div を使用する必要がありますか?

4

1 に答える 1

1

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してください。

于 2016-06-01T06:46:46.103 に答える