Boppity Bop
Boppity Bop

Reputation: 10481

Angular lazy load modules in code (no routing)

In aspnet core app I currently have this in app.modules.ts

import {
  DxDataGridModule,
  DxButtonModule,
  DxNumberBoxModule,
  DxTextBoxModule,
  DxSelectBoxModule,
  DxValidatorModule,
  DxValidationGroupModule,
  DxValidationSummaryModule,
  DxTextAreaModule,
  DxLoadPanelModule,
  DxTemplateModule
} from 'devextreme-angular';

my home page uses only 2 of the above. I want to delay loading of the rest up to the moment user navigates to the pages they are used on.

lets say I have home.component, page1.component, page2.component

home uses 2 DX modules and page1 and page2 use various subsets of all of them..

I spent a lot of time honestly trying to comprehend how lazy loading works but failed. read few dozens of blogs - all show how to either load a single component in RouterModule or a single module.

Can I not use RouterModule at all and just load the modules in onInit of home.component? if not - how do I load bunch of modules with await?

RouterModule now is:

{ path: '', component: HomeComponent },
{ path: 'page1', component: Page1Component }, 
{ path: 'page2' , component: Page2Component },

Upvotes: 1

Views: 642

Answers (2)

marjay
marjay

Reputation: 432

If you import the 3rd party modules inside the sub modules, they will only load if the sub module gets loaded. Remove them from your global app.module.ts.

So your main module could look like this:

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    RouterModule.forRoot([
      {
        path: "page1",
        loadChildren: () =>
          import("./module1/module1.module").then(m => m.Module1Module)
      },
      {
        path: "page2",
        loadChildren: () =>
          import("./module2/module2.module").then(m => m.Module2Module)
      }
    ])
  ],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule {}

And your first sub module using only the DxTextBoxModule for example:

@NgModule({
  imports: [
    CommonModule,
    DxTextBoxModule,
    RouterModule.forChild([
      {
        path: "",
        component: Page1Component
      }
    ])
  ],
  declarations: [Page1Component]
})
export class Module1Module {}

Your second sub module using only the DxSelectBoxModule for example:

@NgModule({
  imports: [
    CommonModule,
    DxSelectBoxModule,
    RouterModule.forChild([
      {
        path: "",
        component: Page2Component
      }
    ])
  ],
  declarations: [Page2Component]
})
export class Module2Module {}

Here is a working sample: StackBlitz

Upvotes: 1

Srikar Phani Kumar M
Srikar Phani Kumar M

Reputation: 1384

For this particular issue, Angular introduced the lazy-loading concept.

What you need to do here is, each component that you mentioned above, home, page-1 and page-2 each component should be made into a module and then you can use the lazy-loading.

The file structure should be something like this:

home
|__home.component.html
 __home.component.scss
 ___home.component.spec.ts
 ___home.component.ts
 ___ home.module.ts


// This particular home.module.ts will have homeComponent as declarations and its necessary imports and exports. 

// This will be the same for page-1 and page-2 as well. 

// Now in your routing.module, it will be like this: 

const routes: Routes = [
  {
    path: 'home',
    loadChildren: () => import('./home/home.module').then(m => m.HomeModule)
  },
  {
    path: 'page-1',
    loadChildren: () => import('./page1/page1.module').then(m => m.Page1Module)
  }
];


this will load that part only when the route is inititated

Upvotes: 0

Related Questions