Loading NgModule input elements dynamically using a service

Hi, I am new to angular2 and typescript. I load components dynamically, and I was wondering if there is a way to declare my components using the service in the "declaration" and "entryComponents" modules.

Using typescript, I can achieve this by doing the following:

import { ComponentLoaderService } from './../../services/component-loader.service'; let componentsToLoad = ComponentLoaderService.getComponents(); @NgModule({ declarations: [ componentsToLoad ], entryComponents: [ componentsToLoad ], }) export class testModule {} 

It really works, but only if I compiled and the server works first.

If, I try to recompile and run it, I get this persistent error:

"Error detecting character value values ​​statically. Function calls are not supported. Consider replacing a function or lambda with a link to an exported function"

My other thought was, is there a way to put component loading in the "export class testModule {}" part to populate the array and then pass it to NgModule?

From my current test this won't work, but I'm still new to this, so something may be missing for me.

Hope someone can help. Thanks!

Here is the code that creates the compilation error:

I just made a new test application.

Then in the test-app folder I installed npm.

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 the file /src/app/components.ts.

 import { TestComponent } from './test.component'; export const mainComponents = [ { key: 0, component: TestComponent }, ]; 

I created the 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 with ng serve, I get this error:

10% of the built-in modules 2/2 modules 0 activeError: an error was detected changing the values ​​of the character statically. Function calls are not supported. Consider replacing a function or lambda with a reference to the exported function, resolving the AppModule character in D: /angularjs/test-app/src/app/app.module.ts, resolving the AppModule character in D: / angularjs / test-app / src / app /app.module.ts

+6
source share
1 answer
 @NgModule({ declarations: [], exports: [] }) export class testModule { static withComponents(components: any[]) { return { ngModule: testModule, providers: [ {provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: components, multi: true} ] } } } 

Another 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 { } 

Using ANALYZE_FOR_ENTRY_COMPONENTS here, you can dynamically add multiple items to an NgModule.entryComponents record.

+4
source

Source: https://habr.com/ru/post/1013244/


All Articles