使用服务动态加载NgModule entryComponents [英] Load NgModule entryComponents dynamically using service

查看:242
本文介绍了使用服务动态加载NgModule entryComponents的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的angular2和typcript。
我正在动态加载组件,我想知道是否有一种方法可以使用模块的声明和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'; 

@Component({
template:`test`,
})
export class TestComponent {}
pre>

我修改了/src/app/app.module.ts看起来像这样。

 导入{BrowserModule}从'@ angular / platform-b​​rowser'; 
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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆