Cómo cargar manualmente un módulo perezoso?


He intentado cargar módulos sin usar enrutadorSystemJsNgModuleLoader, pero no pudo hacerlo funcionar:

this.loader.load(url).then(console.info);

Estoy obteniendo Cannot find module xxx para cualquier cadena que use para URL (aboslute/relative urls/paths... probado muchas opciones). Miré a través del código fuente del router y no pude encontrar nada más que esto SystemJsNgModuleLoader. Ni siquiera estoy segura de que deba usar esto...


Esta pregunta fue hecha ayer en la conferencia ng-europe 2016 - Miško y Matias respondieron: {[12]]}

Miško Hevery: Uno solo tiene que obtener el módulo, desde allí puede obtener el control de component factory y puede cargar dinámicamente component factory en cualquier lugar que desee en la aplicación. Esto es exactamente lo que el router hace internamente. Así que es bastante estrecho para ti hacer eso también.

Matias Niemelä Lo único especial a tener en cuenta es que en el módulo [Ng] hay algo llamado entryComponents y que identifica componentes que podrían ser perezosos loaded-esa es la entrada en ese conjunto de componentes. Así que cuando tienes módulos que están cargados perezosamente, por favor pon las cosas en entryComponents.

...pero no es que el estrecho hacia adelante sin ejemplos y documentos pobres sobre el tema (;

¿Alguien sabe cómo cargar módulos manualmente, sin usar Route.loadChildren? Cómo obtener el módulo y qué es exactamente las cosas que deberían entrar en entryComponents (leí FAQ , pero no puedo intentarlo sin cargar realmente module)?

 38
Author: Sasxa, 2016-10-27

2 answers

Actualizar Angular 6

Véase @RomainLT respuesta

Versiones anteriores

Cualquiera sabe cómo cargar módulos manualmente, sin usar Ruta.¿loadChildren?

Podría verse así: {[18]]}

this.loader.load('./src/test.module#TestModule').then((factory: NgModuleFactory<any>) => {
  console.log(factory);
});

TestModule se encuentra en ./ src / test.módulo.ts file (ruta absoluta)

Ejemplo de Émbolo

Aquí también hay más avanzado ejemplo:

Si no carga el componente declarativamente como:

<my-comp></my-comp>

Dentro de su plantilla, si desea usar este componente para cargar dinámicamente, debe incluir este componente en entryComponent mediante uno de los siguientes métodos:

El compilador crea fábricas como esta:

Para cada componente de entrada - host.factory.js

Para cada componente component.ngfactory.js

Véase también

Ejemplo para Angular-cli

App.módulo.ts

providers: [
  SystemJsNgModuleLoader,
  provideRoutes([
     { loadChildren: 'app/lazy/lazy.module#LazyModule' }
  ])
],

App.componente.ts

export class AppComponent implements  OnInit {
    title = 'Angular cli Example SystemJsNgModuleLoader.load';

    @ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;

    constructor(private loader: SystemJsNgModuleLoader, private inj: Injector) {}

    ngOnInit() {
        this.loader.load('app/lazy/lazy.module#LazyModule').then((moduleFactory: NgModuleFactory<any>) => {
            const entryComponent = (<any>moduleFactory.moduleType).entry;
            const moduleRef = moduleFactory.create(this.inj);

            const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent);
            this.container.createComponent(compFactory);
        });
    }
}

También funcionará con AOT

Githug repo angular-cli-lazy

Carga lenta con webpack y AOT

Compilación utilizando ngc

Compilador de inicialización usando la siguiente fábrica

export function createJitCompiler () {
    return new JitCompilerFactory([{useDebug: false, useJit: true}]).createCompiler();
}

Repositorio de Github

 36
Author: yurzui,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-04 05:11:32

[Angular 6]

Hola,

Comparto mi solución aquí porque no encontré cómo descargar sin router en stackoverflow .

El camino de Yurzui funciona, pero usa el módulo Router para compilar el módulo perezoso, mientras que yo no quería usarlo.

En nuestro archivo src/angular.json podemos pedirle a @angular/cli que compile un módulo aparte.

Para eso agregamos la clave lazyModules en "project" > "your-app-name" > "architect" > "build" > "opcion".

Así:

  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects", 
  "projects": {
    "lazy-load-app": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "prefix": "app",
      "schematics": {},
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/lazy-custom-element-app",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.css"
            ],
            "scripts": [],
            "lazyModules": [
              "src/app/lazy-load/lazy-load.module",
              "src/app/another-lazy-load/another-lazy-load.module"
            ]

Entonces podemos llamar y cargar nuestro módulo compilado.

Así:

export class LoaderComponent implements OnInit {

      // tag where we gonna inject the lazyload module and his default compononent "entry"
      @ViewChild('container', { read: ViewContainerRef }) viewRef: ViewContainerRef;

      constructor(
        private loader:     NgModuleFactoryLoader,
        private injector:   Injector,
        private moduleRef:  NgModuleRef<any>,) {
      }

      ngOnInit(): void {
       this.loader.load(this.pathModuleTemplate).then((moduleFactory: NgModuleFactory<any>) => {
          // our module had a static property 'entry' that references the component that  want to load by default with the module
          const entryComponent = (<any>moduleFactory.moduleType).entry;
          const moduleRef = moduleFactory.create(this.injector);
          const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent);
          this.viewRef.createComponent(compFactory);
        });
      }
}

Fuente: https://github.com/angular/angular-cli/blob/9107f3cc4e66b25721311b5c9272ec00c2dea46f/packages/angular_devkit/build_angular/src/server/schema.json

Esperando que pueda ayudar a alguien:)

 2
Author: RomainLT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-03 12:34:55