我也经历过同样的问题。我就是这样做的。比如说,
UserComponent needs to be loaded dynamically
使用登录页上的AOT编译。
使用者单元输电系统
@NgModule({
...
entryComponents: [UserComponent]
})
export class UserModule {
static entry = UserComponent
}
您的基本登录页可以是:
动态组成部分htlm公司
<div>
<ng-template #pageContainer></ng-template>
</div>
<div *ngFor="let page of pageData">
<div (click)="selectPage(page)">
<div>{{page.title}}</div>
</div>
</div>
当您从登录页选择页面(即尝试动态加载组件)时,请提供相应模块的绝对路径。因此
currentPage.modulePath
对于用户页面,可能类似于
app/modules/pages/user/user.module#UserModule
. 最后,您可以这样加载条目组件:
openWebApp(path: string) {
this.systemJsNgModuleLoader.load(path)
.then((moduleFactory: NgModuleFactory<any>) => {
const entryComponent = (<any>moduleFactory.moduleType).entry;
const moduleRef = moduleFactory.create(this.injector);
const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent);
this.componentRef = this.pageHost.createComponent(compFactory);
});
}
因此,您的动态组件如下所示:
动态组成部分输电系统
import { Component, Input, Output, NgModuleFactory, ViewContainerRef, Compiler, ComponentFactory, ComponentFactoryResolver, ModuleWithComponentFactories, ComponentRef, ReflectiveInjector, SystemJsNgModuleLoader, OnInit, OnDestroy, ViewChild, Injector } from '@angular/core';
import { Http } from '@angular/http';
import { Observable, Subscription } from 'rxjs/Rx';
import { COMPILER_PROVIDERS } from '@angular/compiler';
import * as _ from 'lodash';
import { Page } from './interfaces/page';
import { PageService } from './services/page.service';
import { ActivePageService } from './services/active-page.service';
@Component({
selector: 'app-dynamic-viewer',
host: { 'class': 'template-wrapper dynamicviewer' },
templateUrl: './dynamic.component.html',
styleUrls: ['./dynamic.component.less'],
providers: [PageService, ActivePageService]
})
export class DynamicComponent implements OnInit, OnDestroy {
componentRef: ComponentRef<any>;
@ViewChild('pageContainer', { read: ViewContainerRef }) public pageHost;
public activePagesData: string[];
public pageData: Page[];
public currentPage: Page;
private injector: Injector;
private compiler: Compiler;
constructor(
injector: Injector,
private activePageService: ActivePageService,
private pageService: PageService,
private viewContainerRef: ViewContainerRef,
private componentFactoryResolver: ComponentFactoryResolver,
private systemJsNgModuleLoader: SystemJsNgModuleLoader
) {
this.injector = ReflectiveInjector.resolveAndCreate(COMPILER_PROVIDERS, injector);
this.compiler = this.injector.get(Compiler);
}
ngOnInit() {
this.getActivePageData();
}
selectPage(page: Page) {
if (page.active) {
this.currentPage = page;
if (this.componentRef) {
this.componentRef.destroy();
}
this.openWebApp(this.currentPage.modulePath);
}
}
openWebApp(path: string) {
this.destoryComponent();
this.systemJsNgModuleLoader.load(path)
.then((moduleFactory: NgModuleFactory<any>) => {
const entryComponent = (<any>moduleFactory.moduleType).entry;
const moduleRef = moduleFactory.create(this.injector);
const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent);
this.componentRef = this.pageHost.createComponent(compFactory);
});
}
destoryComponent() {
if (this.componentRef) {
this.componentRef.destroy();
}
}
ngOnDestroy() {
this.destoryComponent();
}
getPageData() {
this.pageService.getPageData().subscribe(res => {
for (const page of res) {
page.active = (this.activePagesData.indexOf(page.name) !== -1)
}
this.pageData = res;
});
}
getActivePageData() {
this.activePageService.getActivePageData().subscribe(res => {
this.activePagesData = res;
this.getPageData();
});
}
}