How to Lazy Load Components in Angular 4 in Three Steps

 

// angular按模块开发,跟模块,特性模块,核心模块(整个应用只在跟模块只加载一次),惰性加载模块等

只是有一个问题,即在惰性加载模块里(selector方式的模板方式,即

<app-title [subtitle]="subtitle"></app-title>

),调用特性模块或者核心模块的component对应的selector时,总是提示错误,即核心模块或者特性模块的component共享到惰性加载的模块时,有问题

 

 

'app-title' is not a known element:
1. If 'app-title' is an Angular component, then verify that it is part of this module.
2. If 'app-title' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("
    [ERROR ->]<app-title ></app-title>

 

网上有人遇到同样的问题,https://github.com/angular/angular/issues/12809,貌似没有解决

https://angular.cn/guide/ngmodule

 

 

// 另一个模块惰性加载的例子

https://angularfirebase.com/lessons/how-to-lazy-load-components-in-angular-4-in-three-steps/

Step 1 - Create a new App with Routing

初始化一个带routing的新project

ng new lazyDemo --routing

 

Now add a link to the lazy url in the app component.

 

 

<button routerLink="/lazy/load-me"></button>

<router-outlet></router-outlet>

 

Step 2 - Generate the “Lazy” Module

 

Let’s create a module that will be lazy loaded, along with a couple components. The --flat flag prevents a directory from being created, then we can easily add components to the module via the Angular CLI.
ng g module lazy --flat
ng g component lazy-parent --module lazy
ng g component lazy-child --module lazy

 

Step 3 - Point the App Router to the Lazy Module

Lazy loading is a technique in Angular that allows you to load JavaScript components asynchronously when a specific route is activated. This can add some initial performance during the initial load, especially if you have many components with complex routing. There are some good posts about lazy loading in angular, but I wanted to simplify it further. This lesson will show you how to enable lazy loading in 3 easy steps with a brand new app.

demo of lazy loading in Angular 4

Step 1 - Create a new App with Routing

Our app will load the AppComponent by default at the root URL, then when the user navigates to lazy/load-me, the lazy module will be loaded asynchronously.

 

ng new lazyDemo --routing

Now add a link to the lazy url in the app component.

 

<button routerLink="/lazy/load-me"></button>

<router-outlet></router-outlet>

Step 2 - Generate the “Lazy” Module

Let’s create a module that will be lazy loaded, along with a couple components. The --flat flag prevents a directory from being created, then we can easily add components to the module via the Angular CLI.

 

ng g module lazy --flat

ng g component lazy-parent --module lazy

ng g component lazy-child --module lazy

Inside the lazy module we need to import the RouterModule. Two things to notice here:

  1. The route path to the component is path: 'load-me', even though it will actually be activated on lazy/load-me. This is a child route, which you will see come together in step 3
  2. The RouterModule calls forChild(routes).
 

import { NgModule } from '@angular/core';

import { CommonModule } from '@angular/common';

import { LazyParentComponent } from './lazy-parent/lazy-parent.component';

import { LazyChildComponent } from './lazy-child/lazy-child.component';

import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [

{ path: 'load-me', component: LazyParentComponent }

];

@NgModule({

imports: [

CommonModule,

RouterModule.forChild(routes)

],

declarations: [

LazyParentComponent,

LazyChildComponent

]

})

export class LazyModule { }

And here’s what the LazyParentComponent looks like. Just looping over the child component a few times.

 

<div *ngFor="let name of ['Foo', 'Bar', 'Baz']">

<p>Hi, my name is {{name}}. I'm a lazy child component.</p>

<lazy-child></lazy-child>

</div>


Your Angular CLI config might append an app prefix to the component selector name. If so, make sure remove the prefix and for the last section to work properly. For example…

@Component({ selector: 'lazy-child' })

Step 3 - Point the App Router to the Lazy Module

The final step is to point the lazy route to the lazy module from the app router. We can do this with the loadChildren property with the path to the module file, then reference the module itself with a hash #. This tells angular to only load LazyModule when the lazy url is activated.

 

import { NgModule } from '@angular/core';

import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [

{ path: 'lazy', loadChildren: './lazy.module#LazyModule'}

];

@NgModule({

imports: [RouterModule.forRoot(routes)],

exports: [RouterModule]

})

export class AppRoutingModule { }

Verify Lazy Loading is Working

Let’s make sure Lazy Loading is working. In chrome, open developer tools and click the network tab. When you navigate to the lazy url, you should see a 0.chunk.js file rendered. In this demo, you can see it took 2ms to load.

The lazy loaded module is the last  chunk.js file in the chrome network logsThe lazy loaded module is the last chunk.js file in the chrome network logs

When you take a look inside this file, you should see a bunch of webpack JavaScript code with related to the lazy module and its components.

Looking inside, we see that is a bunch of JavaScript webpack codeLooking inside, we see that is a bunch of JavaScript webpack code

That’s it for lazy loading components in Angular. Good luck!

 

 

------------------------------------------------------------------

app.module.ts

export const createTranslateLoader = (http: HttpClient) => {
    return new TranslateHttpLoader(http, './assets/i18n/', '.json');
};

export class MyMissingTranslationHandler implements MissingTranslationHandler {
    handle(params: MissingTranslationHandlerParams) {
        return 'Missing text defined in multilanguage file';
    }
}

@NgModule({
    imports: [
        BrowserModule,
        HttpModule,
        JsonpModule,
        HttpClientModule,
        BrowserAnimationsModule,
        TranslateModule.forRoot({
            loader: {
                provide: TranslateLoader,
                useFactory: (createTranslateLoader),
                deps: [HttpClient]
            },
            missingTranslationHandler: { provide: MissingTranslationHandler, useClass: MyMissingTranslationHandler },
            useDefaultLang: true,
            isolate: false
        }),
        LoginModule,
        CoreModule.forRoot({ userName: '' }),
        AppRoutingModule
    ],
    declarations: [
        AppComponent,
        PageNotFoundComponent,
        AppBaseComponent
    ],
    providers: [
        { provide: LocationStrategy, useClass: HashLocationStrategy },
        { provide: RequestOptions, useClass: DefaultRequestOptions },
        **Service
    ],
    bootstrap: [AppComponent],
    entryComponents: []
})
export class AppModule {

}

app-routing.module.ts

const appRoutes: Routes = [

    { path: '', redirectTo: '/login', pathMatch: 'full' },
    {
        path: 'lazyabc', component: AppBaseComponent,
        children: [
            { path: '', loadChildren: 'app/xxx/abc/Abc-module#AbcModule' }
        ]
    }
    { path: '**', component: PageNotFoundComponent }

];

@NgModule({
    imports: [
        RouterModule.forRoot(
            appRoutes,
            {
                // enableTracing: true // <-- debugging purposes only, disable it in real prod env
                // , useHash: true
                // , preloadingStrategy: PreloadAllModules
                // , preloadingStrategy: SelectivePreloadingStrategy, useHash: true
            }
        )
    ],
    exports: [
        RouterModule
    ],
    providers: []
})
export class AppRoutingModule {

}

 

@NgModule({
    imports: [RouterModule.forChild([
        { path: 'login', component: LoginFormComponent }
    ])],
    exports: [RouterModule]
})
export class LoginRoutingModule { }
Abc-routing.module.ts

@NgModule({
    imports: [RouterModule.forChild([
        { path: '', redirectTo: 'list', pathMatch: 'full' },
        {
            path: 'list',
            component: ABCComponent
        },
        {
            path: 'abcSub1',
            component: AbcSub1Component,
        },
        {
            path: 'abcSub2',
            component: abcSub2Component,
        }
    ])],
    exports: [RouterModule]
})
export class AbcRoutingModule { }

app.component.ts

app.component.html

<div id="comp" class="">
    <router-outlet></router-outlet>
</div>

app-base.component.ts

@Component({
  selector: 'app-base',
  template: `
        <app-nav-bar></app-nav-bar>
        <router-outlet></router-outlet>
      `
})

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值