2017-02-27 6 views
2

これで、AoTを使用せずに動的にコンポーネントをロードするモジュールを作成しようとしていました。これは挑戦であることが証明されていますが、私は本当に近くになっています。 ComponentFactoryに格納されているすべてのコンポーネントを取得するにはどうすればよいですか?私の動的ロードモジュールのAoTを壊すことなくコンポーネントを動的にロードする - Angular2

MIJ app.module.ts IにおいてforRoot(の構成要素の配列を渡す):私のdynamic-load.module.ts

imports: [ 
    DynamicLoadModule.forRoot(dynamicComponents), 
] 

IはAngular2 ComponentFactoryにそれらのすべてを追加します。

static forRoot(components: any[]) { 
     return { 
      ngModule: DynamicLoadModule, 
      providers: [{ 
       provide: ANALYZE_FOR_ENTRY_COMPONENTS, 
       useValue: components, 
       multi: true, 
      }, { 
       provide: DynamicLoadService, 
       useValue: new DynamicLoadService(components) 
      }] 
     }; 
    } 

問題はDynamicLoadServiceにあります。これはAoTを乱用しています。私は文書化されたエクスポート関数を試してみましたが、この方法ではサービスにパラメータとしてcomponentsを渡すことができないため、これで問題は解決されません。その後、私はその後、コンパイルされていないコンポーネントを持っていたので役に立たないのもありましたOpaqueTokenの使用によって私のdynamic-load.moduleに成分を通過しようとしたので、

let heroServiceFactory = (logger: Logger, userService: UserService) => { 
    return new HeroService(logger, userService.user.isAuthorized); 
}; 

export let heroServiceProvider = 
    { provide: HeroService, 
    useFactory: heroServiceFactory, 
    deps: [Logger, UserService] 
    }; 

:だからthe Angular documentationで見つかった以下は、私の問題のためのソリューションを提供していません私のモジュールは多くの柔軟性を失いました。

私は結論に達しました。ComponentFactoryのすべてのコンポーネントの配列が必要な場合は、それらをすべて取得する方法が必要です。
ここで、ComponentFactoryResolverを使用して名前に基づいて1つのテンプレートを取得すると、それらをすべて取得するか、少なくとも工場のコンポーネントのすべての名前を取得する必要があります。

if (selectedComponent !== '') { 
    if (typeof this.currentComponent !== 'undefined') { this.currentComponent.destroy(); } 

    const components = this.dynamicLoadService.getComponents(), // --> instead of getting a list of available components through this service which needs the factory that blocks AoT, I should just be able to retrieve all available components from the ComponentFactory 
      component: any = components.find((x) => x.name.toLowerCase().indexOf(selectedComponent) > -1), 
      compFactory = this.cfr.resolveComponentFactory(component); 

    this.currentComponent = this.vcr.createComponent(compFactory); 
    this.currentComponent.instance.data = this.componentData; 
} 

答えて

2

編集 だから、最初の答えは非常に問題を解決していないが、別の有用な人は私がAngular Githubを通じて問題を解決する手助けすることができました。

次のように最終的に私のコードが見えます:

import { NgModule, ANALYZE_FOR_ENTRY_COMPONENTS, Inject } from '@angular/core'; 
import { DynamicLoadService } from './dynamic-load.service'; 

import { DynamicLoadComponent } from './dynamic-load.component'; 

export function DynamicLoadFactory(cmps) { 
    return new DynamicLoadService(cmps); 
} 

@NgModule({ 
    declarations: [ 
     DynamicLoadComponent 
    ], 
    exports: [ 
     DynamicLoadComponent 
    ] 
}) 
export class DynamicLoadModule { 
    static forRoot(components: any[]) { 
     return { 
      ngModule: DynamicLoadModule, 
      providers: [{ 
       provide: ANALYZE_FOR_ENTRY_COMPONENTS, 
       useValue: components, 
       multi: true 
      }, 
      { 
       provide: 'ENTRIES', 
       useValue: components 
      }, 
      { 
       provide: DynamicLoadService, 
       useFactory: DynamicLoadFactory, 
       deps: [[new Inject('ENTRIES')]] 
      }] 
     }; 
    } 
} 

としてはANALYZE_FOR_ENTRY_COMPONENTSは、依存性注入ツリー(ソースhereを探す)の一部ではない私に指摘されました。したがって、上記の回避策はその問題を処理します。


私に答えが届いていたので、Angular Githubでとても役に立ちました。

export function DynamicLoadFactory(cmps) { 
    return new DynamicLoadService(cmps); 
} 

export class DynamicLoadModule { 
    static forRoot(components: any[]) { 
     return { 
      ngModule: DynamicLoadModule, 
      providers: [{ 
       provide: ANALYZE_FOR_ENTRY_COMPONENTS, 
       useValue: components, 
       multi: true, 
      }, { 
       provide: DynamicLoadService, 
       useFactory: DynamicLoadFactory, 
       deps: [new Inject(ANALYZE_FOR_ENTRY_COMPONENTS)] 
      }] 
     }; 
    } 
} 

source at Github

は は

それは私がちょうど

ちょうど今、このようになりますDynamicLoadService

ANALYZE_FOR_ENTRY_COMPONENTSを注入すべきであることを私に示唆されました

関連する問題