angular - 使用服务动态加载 NgModule entryComponents

标签 angular typescript dynamic components

您好,我是 angular2 和 typescript 的新手。 我正在动态加载组件,我想知道是否有一种方法可以使用模块的“声明”和“entryComponents”中的服务来声明我的组件。

使用 typescript ,我可以通过执行以下操作来实现它:

import { ComponentLoaderService } from './../../services/component-loader.service';

let componentsToLoad = ComponentLoaderService.getComponents();

@NgModule({
  declarations: [ componentsToLoad ],
  entryComponents: [ componentsToLoad ],
})
export class testModule {}

这确实有效,但前提是我已经编译并且服务器首先运行。

如果我尝试重新编译并运行它,我会得到这个常量错误:

“静态解析符号值时出错。不支持函数调用。考虑将函数或 lambda 替换为对导出函数的引用,”

我的另一个想法是,有没有办法将组件的加载放在“export class testModule {}”部分来填充数组,然后将其传递给 NgModule?

从我目前的测试来看,它不起作用,但我对此还是个新手,所以我可能会遗漏一些东西。

希望有人能帮忙。 谢谢!

这是造成编译错误的代码:

我刚刚做了 ng new test-app。

然后在 test-app 文件夹中我安装了 npm。

我创建了/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。

import { TestComponent } from './test.component';

export const mainComponents = [
    { key: 0, component: TestComponent },        
];

我创建了一个文件/src/app/test.component.ts。

import { Component } from '@angular/core';

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

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

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 编译时,我得到这个错误:

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 条目。

关于angular - 使用服务动态加载 NgModule entryComponents,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41200544/

相关文章:

angular - 具有多种内容类型的 ContentChildren

javascript - 属性 Angular 2 的绑定(bind)不会更新具有绑定(bind) ID 的关联输入

typescript - 如何使用 ionic2 的 braintree-web js 文件生成付款随机数

javascript - useQuery 的 onError 回调函数(react-query)中错误对象为 null

reactjs - 如何在 React 中单击鼠标的位置动态添加 div?

Angular/Express/Passport - 使用 Google : No 'Access-Control-Allow-Origin 进行身份验证

javascript - Angular 2 i18n 动态/即时翻译

javascript - Typescript - 在函数返回 block 中使用 then 的值

c# - 动态 linq 中的 Regex.IsMatch()

ios - 根据按钮数量设置 CollectionView 单元格高度