web-dev-qa-db-ja.com

サービスを使用してNgModuleentryComponentsを動的にロードします

こんにちは私はangular2とTypeScriptに不慣れです。コンポーネントを動的にロードしていますが、モジュールの「declarations」と「entryComponents」でサービスを使用してコンポーネントを宣言する方法があるかどうか疑問に思っていました。

TypeScriptを使用して、次のようにすることでそれを実現できます。

import { ComponentLoaderService } from './../../services/component-loader.service';

let componentsToLoad = ComponentLoaderService.getComponents();

@NgModule({
  declarations: [ componentsToLoad ],
  entryComponents: [ componentsToLoad ],
})
export class testModule {}

これは実際には機能しますが、コンパイルしてサーバーが最初に実行されている場合に限ります。

再コンパイルして実行しようとすると、次のエラーが発生します。

「シンボル値を静的に解決するときにエラーが発生しました。関数呼び出しはサポートされていません。関数またはラムダをエクスポートされた関数への参照に置き換えることを検討してください。」

私の他の考えは、コンポーネントのロードを「export class testModule {}」部分に入れて配列を埋め、それをNgModuleに渡す方法はありますか?

私の現在のテストからはそれは機能しませんが、私はまだこれに慣れていないので、何かが足りないかもしれません。

誰かが助けてくれることを願っています。ありがとう!

コンパイルエラーを作成するコードは次のとおりです。

新しいテストアプリを作成しました。

次に、test-appフォルダーでnpminstallを実行しました。

/src/app/services/components-loader.service.tsを作成しました。

import { Injectable } from '@angular/core';
import { ViewContainerRef, ViewChild, ComponentFactoryResolver } from '@angular/core';

@Injectable()
export class ComponentLoaderService {
    constructor(private componentFactoryResolver: ComponentFactoryResolver){}

    static getComponents(components: any[]): any[] {
        var tmp = Array();

        for (var i = 0; i < components.length; ++i){
            if (components[i].key == 0){
                tmp.Push(components[i].component);
            }
        }

        return tmp;
    }

    load(container: ViewContainerRef, components: any[]): void {
        // clear 
        container.clear();

        for (var i = 0; i < components.length; ++i){
            if (components[i].key == 0 || components[i].key == 'site'){
                const childComponent = this.componentFactoryResolver.resolveComponentFactory( components[i].component );

                // at this point we want the "child" component to be rendered into the app.component:
                container.createComponent(childComponent);          
            }            
        }
    }
}

ファイル/src/app/components.tsを作成しました。

import { TestComponent } from './test.component';

export const mainComponents = [
    { key: 0, component: TestComponent },        
];

ファイル/src/app/test.component.tsを作成しました。

import { Component } from '@angular/core';

@Component({
  template: `test`,
})
export class TestComponent {}

/src/app/app.module.tsを次のように変更しました。

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { mainComponents } from './components';
import { ComponentLoaderService } from './services/components-loader.service';

let componentsToLoad = ComponentLoaderService.getComponents(mainComponents);

@NgModule({
  declarations: [
    AppComponent,
    componentsToLoad
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule
  ],
  providers: [],
  bootstrap: [AppComponent],
  entryComponents: [ componentsToLoad ],
})
export class AppModule { }

Ngserveを使用してコンパイルすると、次のエラーが発生します。

10%ビルドモジュール2/2モジュール0 activeError:シンボル値の静的な解決中にエラーが発生しました。関数呼び出しはサポートされていません。関数またはラムダをエクスポートされた関数への参照に置き換え、D:/angularjs/test-app/src/app/app.module.tsでシンボルAppModuleを解決し、D:/ angularjs/test-app /でシンボルAppModuleを解決することを検討してください。 src/app/app.module.ts

10
Kheang Hok Chin
@NgModule({
    declarations: [],
    exports: []
})
export class testModule {
    static withComponents(components: any[]) {
        return {
            ngModule: testModule,
            providers: [
                {provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: components, multi: true}
            ]
        }
    }
}

その他のモジュール:

import { ComponentLoaderService } from './../../services/component-loader.service';

let componentsToLoad = ComponentLoaderService.getComponents();

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        testModule.withComponents([
            ...componentsToLoad
        ])
    ],
    declarations: [
        AppComponent,
        ...componentsToLoad
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}

ここでANALYZE_FOR_ENTRY_COMPONENTSを利用することにより、複数のコンポーネントをNgModule.entryComponentsエントリに動的に追加できます。

7
Bazinga