以下是一个示例解决方案,演示了如何使用Angular 7.0.3 CLI从Webpack捆绑包动态加载外部模块。
首先,确保已经安装了Angular CLI,并创建了一个新的Angular项目。
@angular/cli
:npm install -g @angular/cli@7.0.3
ng new dynamic-loading-example
cd dynamic-loading-example
ng generate module external-module --routing
app.module.ts
中导入ExternalModule
:import { ExternalModule } from './external-module/external-module.module';
app.module.ts
的imports
数组中添加ExternalModule
:@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
ExternalModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.html
中添加一个按钮,用于加载外部模块:
app.component.ts
中添加一个方法,用于动态加载外部模块:import { Component, Compiler, Injector, NgModuleFactoryLoader } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private router: Router, private injector: Injector, private loader: NgModuleFactoryLoader, private compiler: Compiler) { }
loadExternalModule() {
this.loader.load('./external-module/external-module.module#ExternalModuleModule')
.then((moduleFactory) => {
const moduleRef = moduleFactory.create(this.injector);
const routes = moduleRef.injector.get(Router).config;
this.router.resetConfig(routes);
this.compiler.compileModuleAndAllComponentsAsync(moduleRef.moduleType)
.then((compiled) => {
const componentFactory = compiled.componentFactories.find((comp) =>
comp.componentType === routes[0].component
);
const componentRef = componentFactory.create(moduleRef.injector);
const viewContainerRef = this.containerRef.viewContainerRef;
viewContainerRef.clear();
viewContainerRef.insert(componentRef.hostView);
});
});
}
}
这个方法使用NgModuleFactoryLoader
来加载外部模块的工厂,然后通过编译器编译模块和组件,并将组件插入到动态加载的模块中。
external-module-routing.module.ts
中添加一个路由配置:import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { ExternalComponent } from './external/external.component';
const routes: Routes = [
{ path: '', component: ExternalComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ExternalModuleRoutingModule { }
external-module.module.ts
中导入ExternalModuleRoutingModule
和ExternalComponent
:import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ExternalModuleRoutingModule } from './external-module-routing.module';
import { ExternalComponent } from './external/external.component';
@NgModule({
declarations: [ExternalComponent],
imports: [
CommonModule,
ExternalModuleRoutingModule
]
})
export class ExternalModule { }
external.component.ts
:import { Component } from '@angular/core';
@Component({
selector: 'app-external',
template: 'External Module
'
})
export class ExternalComponent { }
app-routing.module.ts
中添加一个路由配置:import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
const routes: Routes = [
{ path: '', component: AppComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }