我尝试使用SystemJsNgModuleLoader
在没有路由器的情况下加载模块,但无法使其工作:
>>> d = datetime.strptime("06:10", "%H:%M")
>>> d
datetime.datetime(1900, 1, 1, 6, 10)
对于我用于URL的任何字符串,我得到this.loader.load(url).then(console.info);
(aboslute / relative urls / paths ...尝试了很多选项)。我浏览了一下路由器源代码,找不到任何其他的Cannot find module xxx
。我甚至不确定我应该使用这个......
昨天在SystemJsNgModuleLoader
会议上提出了这个问题 - Miško&马蒂亚斯回答说:
MiškoHevery: 只需要获取模块,就可以从那里获得组件工厂的保留,并且可以在应用程序中的任何位置动态加载组件工厂。这正是路由器内部所做的事情。因此,你也可以做到这一点。
MatiasNiemelä 唯一需要注意的是,在[Ng]模块上有一些名为
ng-europe 2016
的东西,它标识了可以延迟加载的组件 - 这是该组件集的入口。因此,当您有延迟加载的模块时,请将内容放入entryComponents
。
......但如果没有关于这个问题的例子和不好的文档,那就不是那么紧张的前进了(;
任何人都知道如何在不使用entryComponents
的情况下手动加载模块?如何掌握模块以及应该进入Route.loadChildren
的内容究竟是什么(我读了FAQ,但是无法尝试没有实际加载模块)?
答案 0 :(得分:45)
任何人都知道如何手动加载模块,而不使用 Route.loadChildren?
您可以使用SystemJsNgModuleLoader
获取模块的工厂:
this.loader.load('./src/lazy.module#TestModule').then((factory: NgModuleFactory<any>) => {
console.log(factory);
});
以下是它的外观:
<强> lazy.module.ts 强>
@Component({
selector: 'test',
template: `I'm lazy module`,
})
export class Test {}
@NgModule({
imports: [CommonModule],
declarations: [Test],
entryComponents: [Test]
})
export class LazyModule {
static entry = Test;
}
<强> app.ts 强>
import {
Component, NgModule, ViewContainerRef,
SystemJsNgModuleLoader, NgModuleFactory,
Injector} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
@Component({
selector: 'my-app',
template: `<h2>Test lazy loading module</h2>`,
})
export class AppComponent {
constructor(
private loader: SystemJsNgModuleLoader,
private inj: Injector,
private vcRef: ViewContainerRef) {}
ngOnInit() {
this.loader.load('./src/lazy.module#LazyModule')
.then((moduleFactory: NgModuleFactory<any>) => {
const moduleRef = moduleFactory.create(this.inj);
const entryComponent = (<any>moduleFactory.moduleType).entry;
const compFactory =
moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent);
this.vcRef.createComponent(compFactory);
});
}
}
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent ],
providers: [SystemJsNgModuleLoader],
bootstrap: [ AppComponent ]
})
export class AppModule {}
this.loader.load('./src/test.module#TestModule').then((factory: NgModuleFactory<any>) => {
console.log(factory);
});
<强> Plunker Example 强>
AOT 的预编译模块有两种选择:
使用angular / cli内置功能:
{
"projects": {
"app": {
"architect": {
"build": {
"options": {
"lazyModules": [ <====== add here all your lazy modules
"src/path-to.module"
]
}
}
}
}
}
}
见
<强> app.module.ts 强>
providers: [
SystemJsNgModuleLoader,
provideRoutes([
{ loadChildren: 'app/lazy/lazy.module#LazyModule' }
])
],
<强> app.component.ts 强>
export class AppComponent implements OnInit {
title = 'Angular cli Example SystemJsNgModuleLoader.load';
@ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;
constructor(private loader: SystemJsNgModuleLoader, private inj: Injector) {}
ngOnInit() {
this.loader.load('app/lazy/lazy.module#LazyModule').then((moduleFactory: NgModuleFactory<any>) => {
const entryComponent = (<any>moduleFactory.moduleType).entry;
const moduleRef = moduleFactory.create(this.inj);
const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent);
this.container.createComponent(compFactory);
});
}
}
<强> Github repo angular-cli-lazy 强>
使用webpack和AOT进行延迟加载
使用ngc编译
使用以下工厂初始化编译器
export function createJitCompiler () {
return new JitCompilerFactory([{useDebug: false, useJit: true}]).createCompiler();
}
<强> Github repo 强>
答案 1 :(得分:10)
[角度6]
你好
我在这里分享我的解决方案,因为我没有找到如何在stackoverflow上没有路由器的延迟加载。
Yurzui 的方法有效,但是他使用Router模块来编译惰性模块,而我不想使用它。
在我们的src/angular.json
文件中,我们可以要求 @ angular / cli 单独编译模块。
为此,我们在“项目”>“您的应用名称”>“建筑师”>“构建”>“选项”中添加lazyModules
键。
喜欢这个:
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"lazy-load-app": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/lazy-custom-element-app",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": [],
"lazyModules": [
"src/app/lazy-load/lazy-load.module",
"src/app/another-lazy-load/another-lazy-load.module"
]
然后我们可以调用并加载已编译的模块。
喜欢这个:
export class LoaderComponent implements OnInit {
// tag where we gonna inject the lazyload module and his default compononent "entry"
@ViewChild('container', { read: ViewContainerRef }) viewRef: ViewContainerRef;
constructor(
private loader: NgModuleFactoryLoader,
private injector: Injector,
private moduleRef: NgModuleRef<any>,) {
}
ngOnInit(): void {
this.loader.load(this.pathModuleTemplate).then((moduleFactory: NgModuleFactory<any>) => {
// our module had a static property 'entry' that references the component that want to load by default with the module
const entryComponent = (<any>moduleFactory.moduleType).entry;
const moduleRef = moduleFactory.create(this.injector);
const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent);
this.viewRef.createComponent(compFactory);
});
}
}
希望它可以帮助某人:)