-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Dynamic Lazy Load Module #19
Comments
Hello, thanks for interesting suggestion! Did you tried using Lazy Modules with Ivy Renderer API before? I think it can be more declaratively instead of using old View Engine. Do you want to discuss that feature and implement that via PR? |
Hello, |
I'll close that issue because with Angular Ivy we can load components lazily. You can find out an example in readme or check out that tweet. Thanks! |
Hello @thekiba , // https://github.com/IndigoSoft/ngxd/blob/master/projects/core/src/lib/directive/component.outlet.ts
// from
@Input() ngxComponentOutletNgModuleFactory: NgModuleFactory<any> | null;
// to
@Input() ngxComponentOutletNgModule: Type<any> | null;
...
// https://angular.io/api/core/createNgModuleRef
private createNgModuleRef() {
if (this.ngxComponentOutletNgModule) {
this._ngModuleRef = createNgModuleRef(this.ngxComponentOutletNgModule, this.injector);
}
} So my code from original post will be a bit simpler: (routeConfigs[0].loadChildren() as any).then(module => {
this.component = module.entry;
this.module = module;
}); I also tested your suggestion with Interestingly in angular they still use compiler and NgModuleFactory, even tho they are deprecated. https://github.com/angular/angular/blob/master/packages/router/src/router_config_loader.ts#L71 If you think this changes would be useful I can work on a PR to make the changes. |
Hello, // define your route on the root routes
// this is needed for angular to build your component in the final package, they detect dynamic imports only defined in routes.
const appRoutes: Routes = [
...
{
path: '**',
component: NotFoundComponent,
// redirectTo: 'login'
}, // lazy standalone components routes below, so user never reaches them
{
path: LazyComponents.MY_LAZY_COMPONENT,
loadComponent: () => import('./lazyComponent/lazy.component').then(c=> c.LazyComponent)
}
];
// enum to make things easy
export enum LazyComponents {
MY_LAZY_COMPONENT = 'my-random-path'
}
// app-lazy-load component to fetch the component
import {CommonModule} from '@angular/common';
import {Component, Input, OnInit, Type} from '@angular/core';
import {Router} from '@angular/router';
import {NgxdModule} from '@ngxd/core';
import {from, Observable, of} from 'rxjs';
import {LazyComponents} from '....';
const wrapInObservable = <T>(value: T | Observable<T> | Promise<T>): Observable<T> => {
if (value instanceof Observable) {
return value;
}
if (value instanceof Promise) {
return from(value);
}
return of(value);
};
@Component({
selector: 'app-lazy-load',
templateUrl: './lazy-load.component.html',
standalone: true,
imports: [CommonModule, NgxdModule]
})
export class LazyLoadComponent implements OnInit {
@Input() component: LazyComponents;
@Input() context: object;
component: Type<unknown>;
constructor(private router: Router) {}
ngOnInit() {
const routeConfig = this.router.config.find(config => config.path === this.module);
if (routeConfig && routeConfig.loadComponent && routeConfig.loadComponent instanceof Function) {
wrapInObservable(routeConfig.loadComponent()).subscribe(component => (this.component = component));
} else {
console.error('Lazy component not found.');
}
}
} <ng-container *ngIf="component">
<ng-container *ngxComponentOutlet="component; context: context;"> </ng-container>
</ng-container> // app component in which to load my lazy standalone component
import {Component} from '@angular/core';
import {LazyComponents} from '....';
@Component({
selector: 'app-component',
template: './app-component.component.html',
})
export class AppComponent {
LazyComponents = LazyComponents;
} <app-lazy-load [context]="mycontext" [component]="LazyComponents.MY_LAZY_COMPONENT"></app-lazy-load> |
Hey, we can now lazy load standalone components with ngxd. If the modules are converted to standalone components, there's no need for this workaround. |
Hello,
I managed to implement lazy load a feature module dynamically and load the the component in the DOM using this library for dynamic rendering of the component.
Works in both JIT and AOT runtime.
I think this feature will be great addition to the list of features this library supports.
Steps:
That is all the setup needed to make a feature module lazy load at runtime when needed depending on data you have.
The loading of the module is the same thing as what angular does on lazy routes here but the code is private and not accessible from Router.
If the angular team makes the code public API in the future we can reuse they're
loadModuleFactory
method.Let me know if you have any further questions or need any help integrating this part in the library.
Thanks
The text was updated successfully, but these errors were encountered: