第 13 天 长痛不如短痛!整理专案|feature module、shared module

前情提要

完成了新增英雄页面、英雄资讯元件後,在我们劝诱青铜五小强之前,让我们先停一停,来重构整个专案。

我们将完成下列事项:

  • 建立 Feature Module「英雄模组」,将目前拥有的英雄列表、新增英雄、编辑英雄、英雄资讯表单...放入这个模组中。
  • 新增 Shared Module「Material」模组将 Angular Material 使用到的功能模组统一汇入到这里。

模组化不仅可以让我们更好地封装元件,之後搭配 Feature 路由,甚至可以完成懒加载(Lazy Loading),提升 App 的效能。让我们开始吧!

建立 Angular Material 模组

柿子要挑软的吃!首先我们到 Shared 资料夹,并输入指令:

ng g m angular-material -m app // m for module, -m app 将新增的模组汇入根模组

接着,将原本在 AppModule 汇入(imports)的 Angular Material 功能模组搬移到 AngularMaterialModule中,并记得将它们汇出(exports),这样其它模组才可以使用它们:

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

import { MatCardModule } from '@angular/material/card';
import { MatButtonModule } from '@angular/material/button';
import { MatDividerModule } from '@angular/material/divider';
import { MatListModule } from '@angular/material/list';

@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    MatCardModule,
    MatButtonModule,
    MatDividerModule,
    MatListModule,
  ],
  exports: [
    MatCardModule,
    MatButtonModule,
    MatDividerModule,
    MatListModule,
  ]
})
export class AngularMaterialModule { }

重启专案後,App 正常执行:

https://ithelp.ithome.com.tw/upload/images/20210928/20128395WLKlz6qg5a.png

柿子就是这麽软 >////< 接下来让我们面对比较不软的吧...

建立英雄模组

骗你的啦,其实柿子还是满软的。首先我们先在根目录输入指令:

ng g m hero --route hero // m for module; --route 新增模组路由;

接着让我们先来调整专案资料夹结构。首先,先打开 hero 资料夹(使用 Angular Cli 新增 HeroModule 时会自动产生),新增 pages 资料夹,就如同先前所说的,我们将把页面层级的元件都放在 pages 里。同时在我们移动资料夹的时候,编辑器会提示我们,是否要自动调整所有相关的档案引用路径......当然要啊!

完整的 hero 资料夹档案配置路径如下图:

https://ithelp.ithome.com.tw/upload/images/20210928/20128395txhDmJzj8S.png

记得将刚刚准备好的 AngularMaterialModule 以及 FormsModule (你才能使用 ngModel )汇入到 HeroModule 中,接着让我们愉快地重启专案!

说好的懒载入呢?

在使用 Angular 新增带有路由的模组後,AppRoutingModule 已为我们自动建立懒载入了:

  { path: 'heroes', loadChildren: () => import('./hero/hero.module').then(m => m.HeroModule) },

接着,我们要做的事,就是将原本的路由配置移到 HeroRoutingModule 中,最後 HeroRoutingModule 档案是这样子的:

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

import { AddHeroPageComponent } from './pages/add-hero-page/add-hero-page.component';
import { EditHeroPageComponent } from './pages/edit-hero-page/edit-hero-page.component';
import { HeroDetailComponent } from './pages/hero-detail/hero-detail.component';
import { HeroListComponent } from './pages/hero-list/hero-list.component';

const routes: Routes = [
  {
    path: '',
    children: [
      {
        path: '',
        component: HeroListComponent
      },
      {
        path: 'add',
        component: AddHeroPageComponent
      },
      {
        path: 'edit',
        component: EditHeroPageComponent
      },
      {
        path: ':id',
        component: HeroDetailComponent,
      },
    ]
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class HeroRoutingModule { }

而 AppRoutingModule 则是:

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

const routes: Routes = [
  {
    path: '',
    redirectTo: '/heroes',
    pathMatch: 'full'
  },
  { path: 'heroes', loadChildren: () => import('./hero/hero.module').then(m => m.HeroModule) },
]

@NgModule({
  imports: [
    RouterModule.forRoot(routes)
  ],
  exports: [
    RouterModule
  ]
})
export class AppRoutingModule { }

这样就完成专案结构的重整了!

今天程序码已推上 Github


<<:  学习历程救援事件(灾难复原实例)後续追踪

>>:  [Day 23] 撰写我们的第一个 test double

[Day30] AWS Elastic Load Balancing (ELB)

Elastic Load Balancing 可在多个目标 (例如 Amazon EC2 执行个体、...

Day30 I’m on the next level

Summary 承续昨天所说,我们将PivotTable.js的版面调整,让资料区域的表格和图表可...

14. Log X Notification x Slack

好想被推播啊 身为一个负责的工程师,当系统有错误的时候,总是想收到即时推播讯息该怎麽做? 上一篇有提...

Spring Framework X Kotlin Day 15 AOP

GitHub Repo https://github.com/b2etw/Spring-Kotlin...

系统分析师养成之路—商业思维(外师分享)补充

关於系统分析师、专案经理、商业分析师⋯这些IT角色来说,「商业思维」真的太重要!所以除了跟大家分享我...