2

We have some modules that come with their own navigation bars. These nav bars are actual components and they activated in the global HeaderComponent of the app as soon as the corresponding route is activated.

To pass the navigation component we use the dataproperty of the route in app-routing.module.ts:

import { TestNavigationComponent } from './modules/test/components/test-navigation/test-navigation.component';

{
  path: 'test',
  loadChildren: () => import('./modules/test/test.module').then(m => m.TestModule),
  data: {
    nav: TestNavigationComponent
  },
},

While this works fine, I wonder:

Does this circumvent lazy loading of the module? Is the module loaded anyway, because the navigation component is imported in the gobal app-routing.module.ts already?

If yes, how could I bundle the navigation component along with the module and pass it to the application's header?

The naviagtion is rendered in the header component like this currently:

private updateNavigation(snapshot: ActivatedRouteSnapshot): void {
  const nav: Type<Component> = (snapshot.data as {nav: Type<Component>}).nav;

  if (nav instanceof Type) {
    if (nav === this.navigationType) {
      return;
    }

    this.clearNavigation();
    this.navigationType = nav;

    const factory: ComponentFactory<Component> = this.componentFactoryResolver.resolveComponentFactory(nav);
    this.navigationComponentRef = this.navigationRef.createComponent(factory);

    return;
  }

  for (let childSnapshot of snapshot.children) {
    this.updateNavigation(childSnapshot);
  }
}
lampshade
  • 2,470
  • 3
  • 36
  • 74
  • 1
    Yes if you directly import that component it will be eagerly loaded. For the second question, you can have 2 router outlets 1 for the application header and 1 for the main. And your lazy loaded module can fill the header outlet once it's requested. And this will bring more complexity to your application. – Eldar Jun 07 '21 at 09:26
  • Check [this](https://stackoverflow.com/questions/49536677/using-angular-component-in-lazy-loaded-modules) link. – Apoorva Chikara Jun 07 '21 at 09:29
  • @Eldar That was some great advice. I now have a router outlet for that, which makes everything much easier. – lampshade Oct 28 '21 at 13:01

1 Answers1

1

I'm not sure exactly the reason you're passing the component itself rather than a string, which would allow you inside the module to just use a switch statement to give the correct component.

For visualizing what ends up in each module the --stats-json option for ng build is invaluable.

You can check to see where your components ended up with webpack-bundle-analyzer using the command

npx webpack-bundle-analyzer dist/APPNAME/browser/stats.json

That would (for this case) show your component in your main bundle.


I misunderstood your question at first but I'll leave this here as an aside:

You can now lazy load just components (if they are standalone) in Angular 14 and above.

{
   path: 'faq',
   loadComponent: () => import('./lazy-faq-dialog/lazy-faq-dialog.component').then(m => m.LazyFaqDialogComponent)
}
Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
  • That's actually a nice idea, to create the component programatically. I'll give it a shot. Unfortunately the project is still on v13 and will not be updated before February I think. The anaylzer bundle is awesome. Must check it out. Thanks for that also. – lampshade Oct 28 '22 at 05:50
  • 1
    @lampshade good luck! I managed to update to v14 pretty easily as far as the base update went. But changing components over to standalone is what takes time. One of the biggest issues I came across is this one https://github.com/angular/angular/issues/46351 - so good to bear this in mind before you start. – Simon_Weaver Oct 29 '22 at 01:19