使用服务动态加载 NgModule entryComponents [英] Load NgModule entryComponents dynamically using service
问题描述
您好,我是 angular2 和 typescript 的新手.我正在动态加载组件,我想知道是否有一种方法可以使用模块的声明"和入口组件"中的服务来声明我的组件.
Hi I am new to angular2 and typescript. I am loading components dynamically and I was wondering if there is a way to declare my components using a service in the module's "declarations" and "entryComponents".
使用打字稿,我可以通过执行以下操作来实现它:
Using typescript, I am able to achieve it by doing the following:
import { ComponentLoaderService } from './../../services/component-loader.service';
let componentsToLoad = ComponentLoaderService.getComponents();
@NgModule({
declarations: [ componentsToLoad ],
entryComponents: [ componentsToLoad ],
})
export class testModule {}
这确实有效,但前提是我已经编译并且服务器首先运行.
This actually works, but only if I have compiled and the server is running first.
如果我尝试重新编译并运行它,我会得到这个持续错误:
If, I try to recompile and run it, I get this constant error:
静态解析符号值时出错.不支持函数调用.考虑用对导出函数的引用替换函数或 lambda,"
"Error encountered resolving symbol values statically. Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function,"
我的另一个想法是,有没有办法将组件的加载放在export class testModule {}"部分以填充数组,然后将其传递给 NgModule?
My other thought was, is there a way to put the loading of the components in the "export class testModule {}" portion to fill the array and then pass it to NgModule?
从我目前的测试来看,它不起作用,但我还是新手,所以我可能会遗漏一些东西.
From my current test it doesn't work, but I am still new to this so I might be missing something.
希望有人可以提供帮助.谢谢!
Hope someone can help. Thanks!
这是产生编译错误的代码:
Here is the code that creates the compile error:
我刚刚做了一个新的测试应用程序.
I just did ng new test-app.
然后我在 test-app 文件夹中安装了 npm.
Then in the test-app folder i did npm install.
我创建了/src/app/services/components-loader.service.ts.
I created /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.
I created a file /src/app/components.ts.
import { TestComponent } from './test.component';
export const mainComponents = [
{ key: 0, component: TestComponent },
];
我创建了一个文件/src/app/test.component.ts.
I created a file /src/app/test.component.ts.
import { Component } from '@angular/core';
@Component({
template: `test`,
})
export class TestComponent {}
我将/src/app/app.module.ts 修改为如下所示.
I modified /src/app/app.module.ts to look like this.
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 { }
当我使用 ng serve 编译时,我得到这个错误:
When I compile using ng serve, i get this error:
10% 构建模块 2/2 模块 0 activeError: 遇到错误静态解析符号值.不支持函数调用.考虑将函数或 lambda 替换为对导出函数,解析符号 AppModule 中D:/angularjs/test-app/src/app/app.module.ts,解析符号D:/angularjs/test-app/src/app/app.module.ts中的AppModule
10% building modules 2/2 modules 0 activeError: Error encountered resolving symbol values statically. Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol AppModule in D:/angularjs/test-app/src/app/app.module.ts, resolving symbol AppModule in D:/angularjs/test-app/src/app/app.module.ts
推荐答案
@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 条目中.
By making use of ANALYZE_FOR_ENTRY_COMPONENTS here, you are able to add multiple components to the NgModule.entryComponents entry dynamically.
这篇关于使用服务动态加载 NgModule entryComponents的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!