markdown Angular Lazy Module和一些提醒

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown Angular Lazy Module和一些提醒相关的知识,希望对你有一定的参考价值。

# Angular Lazy Modules and some reminders

## Understanding Angular modules (NgModule) and their scopes

[SOURCE](https://medium.com/@cyrilletuzi/understanding-angular-modules-ngmodule-and-their-scopes-81e4ed6f7407)

**The purpose of a NgModule is to declare each thing you create in Angular, and group them together** (like Java packages or PHP / C# namespaces).

There is two kind of main structures:

-  `declarations` **is for things you’ll use in your templates**: mainly components (~ views: the classes displaying data), but also directives and pipes,
- `providers` **is for services** (~ models: the classes getting and handling data).

```javascript
@NgModule({
  declarations: [SomeComponent, SomeDirective, SomePipe],
  providers: [SomeService]
})
export class SomeModule {}
```

Note: since Angular 6, services don’t need to be registered in a module anymore. The use of `providers` in a NgModule is now limited to overriding existing services.

## NgModule and scopes / visibility
The confusion starts with **components and services not having the same scope / visibility**:

- declarations / **components are in local scope** (private visibility),
- providers / **services are (*generally*) in global scope** (public visibility) 

It means the **components you declared are only usable in the current module**. If you need to use them outside, in other modules, you’ll have to export them:

```javascript
@NgModule({
  declarations: [SomeComponent, SomeDirective, SomePipe],
  exports: [SomeComponent, SomeDirective, SomePipe]
})
export class SomeModule {}
```

On the contrary, **services you provided will generally be available / injectable anywhere in your app**, in all modules. (**exception is for lazy-loaded modules** where service is only available for that module. More on this later).

## When to import a NgModule?
The difference of scope between components and services makes thing messy. So in order to import modules that you need:

```javascript
@NgModule({
  imports: [CommonModule, HttpClientModule, FeatureModule]
})
export class SomeModule {}
```

**you need to know why you import these other modules**.

- Is it to use components (or other template-related things, like directives and pipes)?
- or is is to use services?

Why? Because given the difference of scope between components and services :

- **if the module is imported for components, you’ll need to import it in each module** needing them,
- **if the module is imported for services, you’ll need to import it only once**, in the first app module.

If you fail to understand this, you’ll have errors on components not being available, because you forgot to import their module again.

Or if you import a module for services more than once, it can lead to errors in advanced scenarios like lazy-loading.

## When to import main Angular modules?
**Modules to import each time you need them**
- **`CommonModule`** (all the basics of Angular templating: bindings, `*ngIf`, `*ngFor`…), except in the first app module, because it’s already part of the BrowserModule
- `FormsModule` / `ReactiveFormsModule`
- `MatXModule` and other UI modules
- any other module giving you components, directives or pipes

**Modules to import only once**
- **`HttpClientModule`**
- `BrowserAnimationsModule` or `NoopAnimationsModule`
- any other module providing you services only.
That’s why with Angular CLI, `CommonModule` is automatically imported when you create a new module.

But in real situation, modules can be mixed (containing both components and service), for example,  `RouterModule`.  We will learn a trick to manage these kind of modules later.

But before that

## A bit on Lazy-loaded modules and some reminders
[SOURCE](https://medium.com/@michelestieven/lazy-loading-angular-modules-27856e940bb0)

How to set up lazy loaded modules. 

```typescript
// app.module.ts

// ProductModule, OrderModule, UserModule will get loaded
// lazily.
const AppRoutes: Routes = [
  {
    path: "",
    component: IndexComponent,
  },
  {
    path: "products",
    loadChildren: "./product/product.module#ProductModule"
  },
  {
    path: "order",
    loadChildren: "./order/order.module#OrderModule"
  },
  {
    path: "users",
    loadChildren: "./user/user.module#UserModule"
  }
];

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    CoreModule,
    IndexModule, // <-- this module doesn't get loaded easily
    RouterModule.forRoot(AppRoutes) // <-- this one use forRoot
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}
```

```typescript
// example product.module.ts, order.module.ts, user.module.ts 
//is similar

const ProductRoutes: Routes = [
  {
    // Here, we’re using an empty path because these will be
    // the relative routes for this module, not for the entire
    // application
    path: "",
    component: ProductListComponent,
    pathMatch: "full" 
	  // We are using pathMatch: ‘full’ because our route
    // is an empty one, and we don’t want it to match any 
    // other route
  },
  {
    path: "all-products",
    component: ProductListComponent
  },
  {
    path: "product/:id",
    component: ProductDetailComponent
  }
];


@NgModule({
  imports: [
    CommonModule,
    RouterModule.forChild(ProductRoutes), // <-- this one use forChild
    SharedModule,
  ],
  declarations: [
    ProductComponent,
    BestProductComponent,
    ProductListComponent,
    ProductDetailComponent,
  ],
  exports: [BestProductComponent]
})
export class ProductModule {}
```

For truth’s sake, we can open the browser inspector and go to the *Network* tab: you’ll see that once you navigate to the lazy route, a new `chunk.js` file will be loaded asynchronously: that’s our LazyModule in action.

**Reminder**:
- **Don’t import LazyModule for any reason!** If you do that, you’ll lose all the advantages of lazy-loading and you may have serious problems with debugging: **specifying the module’s path is all we need** to do to associate it with our route, let Angular do the rest.
- **The services provided in your lazy-loaded module will only be available in this lazy-loaded module**, not everywhere in your app.
- Lazy modules have a strange behavior: they have their own injector, which means if they import a module which provides some services, **they’ll create their own instances of those services**. Keep this behavior in mind when we need to deal with mixed modules.

以上是关于markdown Angular Lazy Module和一些提醒的主要内容,如果未能解决你的问题,请参考以下文章

[Angular] Show a Loading Indicator for Lazy Routes in Angular

[Angular 2] Keynote: Lazy Routing -- NGCONF

Angular 4 Lazy loading with named router-outlet 不起作用

神奇脑洞题解——苦恼的Van

在 Angular 4 延迟加载中用模块名称替换块名称

markdown 在Cloud9上运行Angular 2和Angular 4