0

In order to load dynamic componets i use materail tab as follows:

<md-tab-group [selectedIndex]="selectedTabIndex" *ngIf="tabs && tabs.length > 0">
    <md-tab *ngFor="let tab of tabs">
        <template md-tab-label>
            {{tab.title}}
            <span class="k-icon k-i-close mat-tab-close" (click)="close(tab)"></span>
        </template>
        <dcl-wrapper [type]="tab.component"></dcl-wrapper>
    </md-tab>
</md-tab-group>

I want to load components into this tab from different modules. Loading process is done with dcl-wrapper as it is suggested in the following link:

https://stackoverflow.com/a/37154680/5285133

I give the seperate module component to the dcl-wrapper with webpack code splitting strategy.

require.ensure(["../../dmy/dmy.module"], (reqire : any) => {
    let cmp = require("../../dmy/page/page2")["Page2"];
    this.tabs.push({ title: "--", component: cmp });
    this.selectedTabIndex = this.tabs.length - 1;
    this._cdr.detectChanges();
}, "dmy");

But i get "No component factory found for Page2. Did you add it to @NgModule.entryComponents?" error.

I also tried to load seperate module components with SystemJsNgModuleLoader this way:

this._loader.load('../../dmy/dmy.module#DMYModule').then((factory: NgModuleFactory<any>) => {
    console.log(factory);
});

It gives this error:

Error: Cannot find module '../../dmy/dmy.module'.? at webpackEmptyContext

Since i use tab component instead of routing, lazy load is not the solution that i want. So, i look for a way to get the instance of seperate module component.

Do you have any suggestion how i can load a seperate module and its components dynamically?

Community
  • 1
  • 1
  • `No component factory found for Page2.` did you add this component to `entryComponents` array? If so then in which module(or component) have you added it? – yurzui Apr 06 '17 at 09:19
  • `Cannot find module '../../dmy/dmy.module'.` Maybe you need to try other paths i.e `app/dmy/dmy.module#DMYModule` – yurzui Apr 06 '17 at 09:23
  • How does your `DMYModule` look like? – yurzui Apr 06 '17 at 09:23
  • 1. Adding Page2 or any other components to entryComponents is not the way webpack advices. 2. I tried many path variations but this is nothing to do with path, the problem is that SystemJsNgModuleLoader can not be used with webpack I think. 3. DMYModule is a simple module with some test pages in it. – Semih Tosun Apr 06 '17 at 09:32
  • `ComponentFactoryResolver` requires compiled component and it can be achieved only adding this component to `entryComponents` array. This way angulat will compile factory for this component and hold link to this factory inside `ComponentFactoryResolver` – yurzui Apr 06 '17 at 09:35
  • Then, how can i load components dynamically with code splitting and without adding components to entryComponents. – Semih Tosun Apr 06 '17 at 09:38
  • `SystemJsNgModuleLoader` can work with webpack2. It can understand `System.import` but it is deprecated as far as i know – yurzui Apr 06 '17 at 09:38
  • https://github.com/angular/angular-cli/issues/2302 – yurzui Apr 06 '17 at 09:40
  • Do you have your own webpack config? – yurzui Apr 06 '17 at 09:45
  • Yes i have a webpack config one that is taken from one of the git start projects. – Semih Tosun Apr 06 '17 at 09:52
  • System.import("../../dmy/dmy.module").then((data: any) => { console.log(data); //this is DMYModule // how can i get Page2 }); – Semih Tosun Apr 06 '17 at 09:53
  • The same thing angular does in build-in directive `ngComponentOutlet` https://github.com/angular/angular/blob/4.1.0-beta.0/packages/common/src/directives/ng_component_outlet.ts#L99 – yurzui Apr 06 '17 at 10:02
  • My example was broken so i fixed it https://plnkr.co/edit/85zrrDdJoStf0mz7QIHT?p=preview – yurzui Apr 06 '17 at 10:09
  • I still get no component factory found error. This is my webpack config, http://take.ms/uZNYz . I compiled with npm run prepublish. Is it ok? – Semih Tosun Apr 06 '17 at 10:12
  • No. You need to compile it via https://github.com/angular/angular/blob/4.1.0-beta.0/packages/core/src/linker/system_js_ng_module_factory_loader.ts#L69 – yurzui Apr 06 '17 at 10:18
  • Thank you very much, i will share the solution – Semih Tosun Apr 06 '17 at 11:00

1 Answers1

0
System.import("../../dmy/dmy.module.js")
            .then((module: any) => {
                return module["DMYModule"];
            }).then((type: any) => {
                return this._compiler.compileModuleAndAllComponentsAsync(type);
            }).then((moduleWithFactories: ModuleWithComponentFactories<any>) => {
                const factory = moduleWithFactories.componentFactories.find((x: any) => x.componentType.name === "Page1"); 
                this.tabs.push({ title: "--", component: factory["componentType"], factory: factory });
                this.selectedTabIndex = this.tabs.length - 1;
                this._cdr.detectChanges();
            });