Is there a way to lazy load components, not modules, in Angular?

后端 未结 4 2034
南方客
南方客 2021-02-18 16:00

Lazy loading is a commonly used technique. However, in Angular it seems that the granularity level of this technique stops at the module level.

That means that you ca

4条回答
  •  野性不改
    2021-02-18 16:07

    Update, with Angular 9 and Ivy it is possible and relatively easy. First of all you need to have some anchor in your app where you want to load your component, it could be named templateRef if you want multiple different components at the same time or ng-template for single one. To do that (i will use ng-template) in your component.html:

    
    

    component.ts:

    export class ExampleComponent {
        @ViewChild(TemplateRef, { read: ViewContainerRef })
        private anchorRef: ViewContainerRef;
    
        constructor(
            private readonly componentFactoryResolver: ComponentFactoryResolver
        ) {}
    
        private async loadComponent() {
            this.anchorRef.clear(); // clear if some components are already there
            const { component } = await import(
                'path to your component'
            );
            const componentFactory = this.componentFactoryResolver.resolveComponentFactory(
                component
            );
            // We could attach @Input and react to @Output by using below instance if needed.
            // Remember we should handle the ngOnChanges lifecycle hook.
            // For that implementation needed.
            this.anchorRef.createComponent(componentFactory);
        }
    }
    

    All that is left is basically call loadComponent when it's needed;

    If you need some modules, for ex you want to use Angular Material. You need to create simple ngModule without export inside your lazyLoaded component. Like this:

    @Component({...})
    export class Component implements OnInit {
        constructor() {}
    
        ngOnInit() {}
    }
    
    @NgModule({
        declarations: [Component],
        imports: [MatIconModule],
    })
    class TasksListModule {}
    

    Also, you could follow the approach Angular team has in their documentation: https://angular.io/guide/dynamic-component-loader

提交回复
热议问题