使用服务动态加载NgModule entryComponents [英] Load NgModule entryComponents dynamically using service
问题描述
我正在动态加载组件,我想知道是否有一种方法可以使用模块的声明和entryComponents中的服务声明我的组件。
使用typescript,我可以通过执行以下操作来实现:
从'./../../services/component-loader.service';let componentsToLoad = ComponentLoaderService.getComponents(); @ NgModule({declarations:[componentsToLoad],entryComponents:[componentsToLoad],})导入{ComponentLoaderService}导出类testModule {}
这实际上有效,但只有当我已编译并且服务器正在运行。
如果,我尝试重新编译并运行它,我得到这个常量错误:
错误遇到解析符号值为静态不支持函数调用。考虑将函数或lambda替换为导出函数的引用,
我的另一个想法是,有没有办法将组件加载到export class testModule {}部分来填充数组,然后将其传递给NgModule?
从我目前的测试中,它不起作用,但我仍然是新的我可能会缺少一些东西。
希望有人可以帮助
谢谢!
代码创建编译错误:
我刚刚做了新的测试应用程序。
然后在测试-app文件夹我做了npm安装。
我创建了/src/app/services/components-loader.service.ts。
$ b来自'@ angular / core'的$ b pre>
import {Injectable};
导入{ViewContainerRef,ViewChild,ComponentFactoryResolver}
@Injectable()
export class ComponentLoaderService {
constructor(private componentFactoryResolver:ComponentFa ctoryResolver){}
static getComponents(components:any []):any [] {
var tmp = Array();
for(var i = 0; i< components.length; ++ i){
if(components [i] .key == 0){
tmp。推(成分〔Ⅰ〕.component);
}
}
return tmp;
}
load(container:ViewContainerRef,components:any []):void {
// clear
container.clear();对于(var i = 0; i< components.length; ++ i)
{
if(components [i] .key == 0 || components [i] .key =='site'){
const childComponent = this.componentFactoryResolver.resolveComponentFactory(components [i] .component);
//此时我们希望将子组件呈现到app.component中:
container.createComponent(childComponent);
}
}
}
}
从'./test.component'创建一个文件/src/app/components.ts。
import {TestComponent};
export const mainComponents = [
{key:0,component:TestComponent},
];
我创建了一个文件/src/app/test.component.ts。
import {Component} from'@ angular / core';
pre>
@Component({
template:`test`,
})
export class TestComponent {}
我修改了/src/app/app.module.ts看起来像这样。
导入{BrowserModule}从'@ angular / platform-browser';
import {NgModule} from'@ angular / core';
import {FormsModule} from'@ angular / forms';来自'@ angular / http'的
import {HttpModule};
import {AppComponent} from'./app.component';
import {mainComponents} from'./components';
import {ComponentLoaderService} from'./services/components-loader.service';
让componentsToLoad = ComponentLoaderService.getComponents(mainComponents);
@NgModule({
声明:[
AppComponent,
componentsToLoad
],
导入:[
BrowserModule,
FormsModule,
HttpModule
],
providers:[],
bootstrap:[AppComponent],
entryComponents:[componentsToLoad],
} )
export class AppModule {}
当我使用ng服务编译时,我收到这个错误:
10%构建模块2/2模块0 activeError:遇到错误
静态地解析符号值。不支持函数调用。
考虑用
导出函数的引用替换函数或lambda,解析
中的符号AppModule D:/angularjs/test-app/src/app/app.module.ts,解析符号
D中的AppModule:/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: multi:true}
]
}
}
}
其他模块:
导入{ComponentLoaderService}来自'./../../services/component-loader。服务';
让componentsToLoad = ComponentLoaderService.getComponents();
@NgModule({
imports:[
BrowserModule,
FormsModule,
testModule.withComponents([
... componentsToLoad
$ b],
声明:[
AppComponent,
... componentsToLoad
],
bootstrap:[AppComponent]
})
export class AppModule {
}
通过在这里使用ANALYZE_FOR_ENTRY_COMPONENTS ,您可以动态地向NgModule.entryComponents条目添加多个组件。
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:
"Error encountered resolving symbol values statically. Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function,"
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.
Then in the test-app folder i did npm install.
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); } } } }
I created a file /src/app/components.ts.
import { TestComponent } from './test.component'; export const mainComponents = [ { key: 0, component: TestComponent }, ];
I created a file /src/app/test.component.ts.
import { Component } from '@angular/core'; @Component({ template: `test`, }) export class TestComponent {}
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 { }
When I compile using ng serve, i get this error:
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} ] } } }
Other module:
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 { }
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屋!